Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2788471
  • 博文数量: 471
  • 博客积分: 7081
  • 博客等级: 少将
  • 技术积分: 5369
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-04 21:55
文章分类

全部博文(471)

文章存档

2014年(90)

2013年(69)

2012年(312)

分类: C/C++

2012-05-03 09:04:32

题目大意:hdu的计算机要分成两个学院,现在有n种物品,价值为ai的有bi个,要求把这些东西分成价值总和最为接近的两份,如果不能平分,大的在前面。

编程教训:
1、//(遍历每一括号时注意)循环的次数应该等于这一括号里表达式的最高指数

  1. for(i=0;i<=v[1]*m[1];i+=v[1])
  2.             c1[i]=1;
2、两个括号相乘之后(合并之后),这个括号的最高指数为len=v[1]*m[1]+v[i]*m[i]
  要注意保存中间结果,有点类似动态规划了

3、v[i]是作为增量的,括号里的项数由 增量与最高指数 表示

这样的话,看一下一半质量的组成方案是否可行(i=sum/2 c1[i]是否为1):
行,直接输出;
不行,递增输出第一个不为0,另外一个sum-i(大的在前)

Input
Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0A test case starting with a negative integer terminates input and this test case is not to be processed

Sample Input
N是种类,价值为V的数量M,一共N种,以-1结尾

2
10 1
20 1
3
10 1
20 2
30 1
 -1
Sample Output
20 10
40 40


点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<string.h>

  3. int c1[250010],c2[250010];//50 * 50 * 100;
  4. int v[55],m[55];//M<=50个<V,M>,每一个最大值50*100

  5. //(遍历每一括号时注意)循环的次数应该等于这一括号里表达式的最高指数
  6. int main()
  7. {
  8.     int N;
  9.     while(scanf("%d",&N)!=EOF && N>0)
  10.     {
  11.         int i,j,k,_sum=0;
  12.         memset(c1,0,sizeof(c1));
  13.         memset(c2,0,sizeof(c2));

  14.         //记得初始化啊,否则会影响下一次结果
  15.         memset(v,0,sizeof(v));
  16.         memset(m,0,sizeof(m));
  17.         //<v,m>初始化,从1开始
  18.         for(i=1;i<=N;i++)
  19.         {
  20.             scanf("%d %d",&v[i],&m[i]);
  21.             _sum+=v[i]*m[i];
  22.         }
  23.         //计算第一个括号,记得要相乘啊!!因为最高指数是v[]*m[]
  24.         for(i=0;i<=v[1]*m[1];i+=v[1])
  25.             c1[i]=1;
  26.         
  27.         int len=v[1]*m[1];//保存上一个结果的长度
  28.         
  29.         //计算剩下的N-1个括号
  30.             for(i=2;i<=N;i++)
  31.             {
  32.                 for(j=0;j<=len;j++)
  33.                 {
  34.                     for(k=0;k<=v[i]*m[i];k+=v[i])
  35.                         c2[k+j]+=c1[j];//将第二个括号有系数的都加进去
  36.                 }
  37.                 len=len+v[i]*m[i];
  38.                 for(j=0;j<=len;j++)
  39.                 {
  40.                     c1[j]=c2[j];
  41.                     c2[j]=0;
  42.                 }
  43.             }
  44.             
  45.         
  46.             for(i=_sum/2;i>=0;i--)
  47.             {
  48.                 if(c1[i]!=0)//从一半的开始
  49.                 {
  50.                     printf("%d %d\n",_sum-i,i);
  51.                     break;
  52.                 }
  53.             
  54.             }
  55.                 
  56.             
  57.         }
  58.     return 0;
  59. }



阅读(660) | 评论(0) | 转发(0) |
0

上一篇:acm中的打表

下一篇:拓扑排序思想

给主人留下些什么吧!~~