假如有s篇文章,每人审核m篇,每篇n个人审核。
怎么得到需要多少人呢。
例如:
总共有9篇文章(1,2,3,4,5,6,7,8,9),每人3篇,每篇需要3个人审核。
我的算法为:把总文章数s除以每人审核篇数m得到k,然后k乘以每篇n人审核。
算法为:s/m=k*n,如果sm的余数不为零,那么k=k+1然后再乘以n;
上面的例子结果如下:
论文:(123),(456),(789)把论文分成等三份。每份三个人,所以需要9个人。
假如有10篇论文,那么就需要12个人了。(123),(456),(789),(10)分成了四份。
还有,具体到分配的时候怎么保证每个人的论文都不一样呢,上面的结果是每三个人的论文完全一样的。
大家有没有别的好的算法呢。相当的考脑力哦。。
怎么得到需要多少人呢。
例如:
总共有9篇文章(1,2,3,4,5,6,7,8,9),每人3篇,每篇需要3个人审核。
我的算法为:把总文章数s除以每人审核篇数m得到k,然后k乘以每篇n人审核。
算法为:s/m=k*n,如果sm的余数不为零,那么k=k+1然后再乘以n;
上面的例子结果如下:
论文:(123),(456),(789)把论文分成等三份。每份三个人,所以需要9个人。
假如有10篇论文,那么就需要12个人了。(123),(456),(789),(10)分成了四份。
还有,具体到分配的时候怎么保证每个人的论文都不一样呢,上面的结果是每三个人的论文完全一样的。
大家有没有别的好的算法呢。相当的考脑力哦。。
解决方案 »
- 高分求一正则表达式,取两标签之间的值。。
- 读取文本文件的问题
- datagridview中comboBox数据无法获取
- 对于二维List对象list,如何给第3行第2列的元素赋值,又如何取得第3行第2列的元素值
- c#怎么样把一个文件移动到指定文件夹下面(在线等,搞定就给分)
- 引用同一性的问题
- 关于在wpf工程中添加cur图标的问题
- ++++++++++举个例子给50分,如何用'回车键'替代这个“按钮”事件???+++++++++++
- duwamish 仅仅安装 .net framework 可不可以运行?
- 如何获取RichTextBox控件中滚动条的当前位置
- 在线急等!@@@@@着急死了!快帮忙创建excel显示excel
- C# .net 多线程处理
S:总文章
R:总人数
N:每篇人数
M:每人篇数
工作量=S*N=R*M
文章审核量是S*N,除以M就行
小学3年级
你的考虑太片面。
{
s = Math.Ceiling(s/n)*n;
int r = Convert.ToInt32(s*n/m);
return r;
}
S:总文章
R:总人数
N:每篇人数
M:每人篇数
工作量=S*N=R*M
S*N = R*M
S:总文章
R:总人数
N:每篇人数
M:每人篇数R=S*N/M这样算,9篇需要9人,10篇则需要10人。至于具体的分配就可能比较复杂了。
小于3的时候s = Math.Ceiling(s/n)*n;
没怎么考虑清楚..
下班回家吃饭..YEAH
IF小于3的时候用另外的算法
{
s = Math.Ceiling(s/n)*n;
int r = Convert.ToInt32(s*n/m);
return r;
}
S:总文章
R:总人数
N:每篇人数
M:每人篇数
工作量=S*N=R*M
这个算法还是有问题的。当s=9,m=4,n=3就不对了吧。这个时候应该是8个。
用一个数组A[s*m]放需要审记的东西
for(i=0,i<s*m,i++)
A[i]=i%m;
/*A[i]里面放的文件编号,编号由0开始 例如 9篇文章 A[10]=1,放的是1号文件 */
然后只要这样
i=0,j=0,k=0;
while(i<s*m)
{ while(k<n)
{B[j][k]=s[i] /*B数组 j代表的是审记人员编号(0开始),k是他的第K份审记文件.*/
i++;
k++;
}
k=0;
j++;
}
j就是需要的人数了
如果要具体查到哪个人负责哪些
看一下数组B[j][]就知道了
这个算法有2个例外
1: M>S的时候 每个人审计的东西都会重复
2: S<N的时候
我是用一个数组放所需要的东西
拿楼主给的例子
A[]={0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8}
那么
B[0][0]=0,B[0][1]=1,B[0][2]=2 也就是0号审计员需要负责 0,1,2号
B[1][0]=3,B[1][1]=4,B[1][2]=5 也就是1号审计员需要负责 3,4,5号
依次类推,直到i=s*m也就是A数组都走了一遍,任务全部完成
如果没有限制
则可以用两个for求出所有的可能
然后再选择要求人数最少的那个m,n值。
如果没有限制
则可以用两个for求出所有的可能
然后再选择要求人数最少的那个m,n值。
------------------------------------------
m,n是设定的,不确定的值。
这样的话,出现的问题是
M>S的时候 每个人审计的东西都会重复
所以,需要的人是S
每个人的任务都一样,是S次,从0审计到S-1号文件
我想了一下,S,N没什么问题
时,得到最佳答案
最少人数为:s/mint aaa(int s)
{
for(int i=1;i<s/2;)
{
int k=0;
if(s%i==0)
{
k=i;
i++;
}
else
i++
}
return k;
}
{
s = Math.Ceiling(s/m)*m; //这里n换成m
int r = Convert.ToInt32(s*n/m);
return r;
}
不知道这样行不行
result=s*n/m;
else
result=error;
文章
1 2 3 4 5 6 7 .... s
人员 1 a b c d e f g .... m
2 m a b c d e f .... m-1
3 m-1 m a b c d e .... m-2
...
n
每人 《至多》 审核m篇文章,每篇文章 《至少》 需要n人审核。
有s篇文章,问 《至少》 需要多少人。现在我们分析问题:1.假设有 1 篇文章,有 n 人,且( m>=1 ),则需要 n 人。 (这步总能懂吧 :) )
2.假设有 _m 篇文章,有 n 人,且( m>=_m ),则需要 n 人。 (n 人是至少的,而且足够:) )
// 现在人多点,超过 m 人,但 _m<=2*m
3.假设有 _m 篇文章,有 n 人,且( m>_m 且 m<=2*m ),则需要 2n 人。(这步理解吗)
前 n 人处理前 m 篇,后 n 人处理 m-_m 篇4.一般情况呢 ? 我不给具体推导过程,给出个公式 :
(s/m)*n .. 应该能理解吧如果还有问题 :到我的 blog : blog.csdn.net/vic_st
计人数 为 k 。
为了 Con(ind), 必须有 k<C(m,s) :(否则必然有两人有相同文章审阅集合)
不考虑 Con(ind),得 k'=(s/m)*n;因此,有 (s/m)*n<=C(m,s) .. 可见要满足 Con(ind), 对 n 有一定限制。现在假设有 C(m,s) 人,每人对应 s 选 m 的一种组合。
则 每篇文章将被审核 C(m,s) * m / s 次。 ( see? )
上式= C(m-1,s-1) ........明天继续写。
R:总人数
N:每篇人数
M:每人篇数N*(S-M*R)>=0代入求R,若R小于等于的值为整数,则该值为所求值;如RR小于等于的值为小数,则在把该数凑整(不能四舍五入)。
R:总人数
N:每篇人数
M:每人篇数M*R-N*S>=0代入求R,若R大于等于的值为整数,则该值为所求值;如R大于等于的值为小数,则在把该数凑整(不能四舍五入)。
R:总人数
N:每篇人数
M:每人篇数求需要最少人数
M*R-N*S>=0代入求R,若R大于等于的值为整数,则该值为所求值;如R大于等于的值为小数,则在把该数去余数取整数的基础上加N(不能四舍五入)。
n*s=m*x
s篇文章,审核m篇,每篇n个人审核,x个人
x=ns/m
想那么多干吗?
{
public static void main(String [] args){
int [] book = new int[100];
int people=0;
int checkCont=0;
int i=0; while(true){
checkCont=0;
for(i=0;i<book.length;i++){
if(book[i]<3){
book[i]++;
checkCont++;
}
if(checkCont>=3){
people++;
break;
}
} if(checkCont<3&&checkCont>0)
people++; if(i==book.length&&book[i-1]==3){
break;
} } System.out.println("需要人数:"+people);
}
}
西格码(k)=s*n
t=0 p>=n 0<k<m对这个算式些程序就可以了
p〉=n
0〈k〈=m判断几个变量的临界还不简单~~~
而M*R应该是大于等于S*N的,即可能有人没有达到M次工作量.实际分配中,因为几个量都是不定的,极有可能所分配的值不会使每个人都恰巧分配到同样多的文章,或者说,硬要同样多的话,就会出现某些人被重复分到相同文章,相同的不再看也等效于少分配一次),就保证不了每个人所看的M个文章是不相同的.所以这个问题的关键是分清主次,关系就应该是S*N<R*M.
怎么得到需要多少人呢。人数 R = s*n/m
分配 则是一个排序的问题,排出全序 每个人顺序取就好了,根据题意最后一个人可能没有m篇
申请m个数组,m个指针,每个数组保存全部文章,
一次移动m个指针中的一个,获得一个组合,
直到获得全部结果的个数
\________n 个1....s_________/
每人抽取 m 篇 (m<s)
---------------------------------------------------------------
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
9篇 每人4篇 每篇3人
1234 5678 3456 2789 4567 1239 189*
我想楼主可能就是觉得在这样的情况下求出所有可能的组合比较麻烦吧!
这样人数还是等于 S * N / M,不能除尽则加多一人。
最简单的算法就是用随机
就像摇奖那样全部放到一起摇一摇(s*n)。每个人再抽出来哈(m)。毕竟中奖不大容易哈。
就是n<s和m<s,
如果不满足这两个条件,
就不能满足“每个人的文件都不同”这个条件,
你如果问我为什么,我只能举例来解释:
我们用边界界定法来讲:
假设S = 10
M和N都为极限10,你有办法每个人的文件都不同吗?
进一步,单独取M或者N为10,另一个任意,能作到吗?
都不能!
#include <stdlib.h>
#include <stdio.h>
#include <time.h>void main( void )
{
int i,j=0;
int r; //随机数
int *a = new int[81];
int *p = new int[27]; srand( (unsigned)time( NULL ) ); for(i=0; i<27; i++)
{
a[i] = i%9+1;
a[i+27] = 1;
a[i+54] = 1;
p[i] = 0;
}do
{
r = rand()%27;
if(j%3==0)
for(i=0; i<27; i++)
a[i+54] = 1;
if(a[r+27] == 1 && a[r+54] ==1)
{
p[j] = a[r];
a[r+27] = 0;
a[r%9+54]=a[r%9+9+54]=a[r%9+18+54]=0;
j++;
}
}while(p[j] == 0);
for( i = 0; i < 9;i++ )
{
printf( "%d-%d-%d ", *(p+i),*(p+i+9),*(p+i+18));
} delete p,a;
}
总人数:R
每人审核:M
每篇人数:N
每个人审核的文章序号:SID[M]
已知:Title[S],M,N
每编文章需要N个人审核,每个人最多M编文章
每个人审核的文章编号都不同(特例除外,如M=N=S等)
求:R
typedef struct
{
int ArticleID[M]; //保存每个人审核的文章编号
int ArticleNum;//实际上每个人审核的文章数,可能小于M
}AuditingArticle;void main()
{
int R=0; //总人数
int i,j; //循环变量
int curPerson=0;//当前分配的最大文件编号
AuditingArticle* AArticle;//定义所有人及每个人审核的文章编号
R=(S*N)/M; //取余
if((S*N)%M)
R++;//获得需要的最多人数
AArticle=(AuditingArticle*)malloc(R*sizeof(AuditingArticle));//开内存
memset(AArticle,0,R*sizeof(AuditingArticle));//清空AArticle变量,全置为0 ,也可以循环赋值置0
//下面的代码就是分配关键 思想其实很简单
//把curPerson看成一个循环链表 从不同的位置顺序分配
for(i=0;i<N;i++) // 把S篇文章分配N次
{
for(j=0;j<S;j++) //总文章
{
curPerson=curPerson%R;
AArticle[curPerson].ArticleID[AArticle[curPerson].ArticleNum]=j;
AArticle[curPerson].ArticleNum++;
}
}
}
最终的效果是:
如1.2.3.4.5.6.7.8.9.10.11 每人可审核4篇,每编需3人审核
Persons=(11*3)/4+1=9;
Person1:1,10,8,6
Person2:2,11,9,7
Person3:3,1,10,8
Person4:4,2,11,9
Person5:5,3,1,10
Person6:6,4,2,11
Person7:7,5,3
Person8:8,6,4
Person9:9,7,5
开始没有看到foren_whb(丰云)兄的,我解决方法和foren_whb(丰云)兄的
一样。
改进1:以上方法很容易推导自己所要审核的文件编号,我们可以增加随机
跳跃数,这样每个人的文章编号都相当随机,修改后的代码为:
int Jump=0;
curPerson=rand()%R;
Jump=rand()%(R/2);
for(i=0;i<N;i++) // 把S篇文章分配N次
{
for(j=0;j<S;j++) //总文章
{
curPerson=curPerson%R;
AArticle[curPerson].ArticleID[AArticle[curPerson].ArticleNum]=j;
AArticle[curPerson].ArticleNum+=Jump;
}
}
}
以下定义为11篇每篇3人,每人4篇import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;public class TestAllocation {
// 人类定义
private static class Person {
private int num = 0;
private String name = null;
private List books = new ArrayList();
public Person (String name, int num) {
this.name = name;
this.num = num;
}
public boolean addBook(Book book) {
if (books.size()==this.num) return false;
books.add(book);
book.num--;
return true;
}
public List getBooks() {
return this.books;
}
public String toString() {
return this.name;
}
}
// 数类定义
private static class Book {
public int num = 0;
private String name = null;
public Book (String name, int num) {
this.name = name;
this.num = num;
}
public String toString() {
return this.name;
}
}
// 每人审批篇数
private static int iBook = 4;
// 每篇审批人数
private static int iPerson = 3;
// 书数组定义
private static Book[] books = new Book[] {new Book("1", iPerson),new Book("2", iPerson),new Book("3", iPerson),new Book("4", iPerson),new Book("5", iPerson),
new Book("6", iPerson), new Book("7", iPerson), new Book("8", iPerson), new Book("9", iPerson),
new Book("10", iPerson), new Book("11", iPerson)
};
public static void main(String[] args) {
LinkedList bookList = new LinkedList();
for (int i = 0; i < books.length; i++) {
bookList.add(books[i]);
}
LinkedList personList = new LinkedList();
int personName = 1;
while (bookList.size()>0) {
Person person = new Person(String.valueOf(personName++), iBook);
while (true) {
if (bookList.size()==0) break;
Book book = (Book) bookList.removeFirst();
if (person.addBook(book)) {
if (book.num!=0) bookList.addLast(book);
continue;
}
bookList.addFirst(book);
break;
}
personList.add(person);
}
// 结果输出
Iterator it = personList.iterator();
while (it.hasNext()) {
Person person = (Person) it.next();
System.out.println("Person name: " + person);
System.out.println("Has Books: ");
for ( int i = 0; i < person.getBooks().size(); i++) {
System.out.println(person.getBooks().get(i));
}
}
}
}
结果:
Person name: 1
Has Books:
1
2
3
4
Person name: 2
Has Books:
5
6
7
8
Person name: 3
Has Books:
9
10
11
1
Person name: 4
Has Books:
2
3
4
5
Person name: 5
Has Books:
6
7
8
9
Person name: 6
Has Books:
10
11
1
2
Person name: 7
Has Books:
3
4
5
6
Person name: 8
Has Books:
7
8
9
10
Person name: 9
Has Books:
11
那么,
1.当n<x时,能过的文章是0.所以必须有x>=n(此时也可保证到了末尾后不会重叠)
2.其它情况下,会剩下的纸条最多不超过n张,此时可解得x个人至少能审核x*m-(n-1)篇文章,反解可推出x.
这个问题我觉得是在问两件事:首先是找人数,第二是找feasible solution. 其实如果把整个问题看成是个bipartite graph G(V,E), V = L + R,L = {所有文章}, R={所有人}, 两个节u \in L, v \in R点相连当切仅当v审u的文章. G的特性就是所有L中节点的degree是n, 所有R中节点的degree是m. 如果通过两种方法数|E|, 那么有 |L|n = |R|m, 所以 |R| = sn/m。这就是所要的人数。这个人数肯定是不能变的,然后就是找feasible solution. 这个用简单的maximum flow就能算了。建构G’ = {s,t}+L+R, L = {所有文章}, R={所有人}。S与所有L节点相连, weight设为n; t与所有R节点相连, weight设为m; L,R中结点两两相连. 然后找s-t之间的最大流. 如果最大流不是n|L|, 那么就没有feasible solution. 如果想看bipartite graph和maximum flow, “Introduction to Algorithm”中有解释. 如果想看更难的network flow的问题, Robert Tarjan有一本”data-structure and network algorithm”. 不过network flow的东西可能operational research 的教材讲得更详细.
这个问题我觉得是在问两件事:首先是找人数,第二是找randome enough feasible solution.其实如果把整个问题看成是个 bipartite graph G(V,E), V = L + R,L = {所有文章}, R={所有人}, 两个节u \in L, v \in R点相连当切仅当v审u的文章. G的特性就是所有L中节点的degree是n, 所有R中节点的degree是m. 如果通过两种方法数|E|, 那么有 |L|n = |R|m, 所以 |R| = sn/m。这就是所要的人数。
这个人数肯定是不能变的,然后就是找random feasible solution. 如果把上述的graph看成matrix, 那么他有跟matrix game差不多的特性,column sum 和row sum一样. 要让这个matrix random enough, 就一个一个column找解. 换一种说法,for 每一个人
在还没被申完的论文中, 随便抽m篇
next 下一个人还没被申完的论文意思为审此论文的人还不足n人.这样的random function collision肯定是有的.而存在两个人使得他们两个人审的论文相同的概率是(1/C(r, s))^2. C(r, s)指r选s. 只有在r跟s相同的情况下,才无解。而用polynomial trial可以让error rate降到可忽略的程度(=1/superpoly). 那位两星的回答,只是说明degenerated case不能解决。
所有C(r, s)变成C(r,m), 无解的条件也说错了,我还没想到正确的条件。不过有点像submodular function....
只要求出最少人数p就可以了
如果s<m
p: 人数
s*n=m*p
求出P如果整数则是结果
小数则取整加1即可
如果 s>m
则p=n
由于题目不明确 我理解不必求出排列,排列的情况多了,有符合条件的,也有一个人重读文章的,
但是对求最小人数没影响
以上愚见 请指教
为了答谢各位朋友,可以去下面连接接分哦。
http://community.csdn.net/Expert/topic/4931/4931648.xml?temp=.8525965