ACM PKU 1837 Balance http://acm.pku.edu.cn/JudgeOnline/problem?id=1837

大牛说这个题目很简单,我认为难-----因为我没有想清楚;

网上的代码很多,但是基本上都是Copy 来 又Copy去的;总之;看的是一个版本还看不明白;

我把解题报告好好写写!

第一:我们最终的目的是找能使天平平衡的方法数;这个只能做背包做了,用01背包不难想,最终的结果就是sign【G】【Mid】数组里面记录的次数;

第二;想清楚为什么不会出现在加入同一个砝码时不会造成计算重叠;只要把一个子问题抽出来看就明白了;

假设出现重叠,那么它的上以状态就已经平衡了,(即到天平中心的距离相等)此处只是借助当前砝码来权衡能不能达到中间位置,此砝码在实际中不起作用;

第三;DP的状态转移方程:sign[i][k + wet[i]*len[j]] += sign[i-1][k];-------01背包模型,变相了!

#include <iostream>
using namespace std;

const int Mid = 8000 ; 
int sign[22][2*Mid];
int len[22],wet[22];

int main ()
{
    int C,G;
int i, j, k;

cin >> C >> G;
for (i = 1;i <= C; i++)
   scanf("%d",&len[i]);
for (i = 1;i <= G; i++)
   scanf("%d",&wet[i]);

memset(sign,0,sizeof(sign));
for (i = 1;i <= C; i++)
   sign[1][Mid + wet[1]*len[i]]++;     //初始化;

for (i = 2;i <= G; i++)
   for (j = 1;j <= C; j++)
    for (k = 1; k <= 2*Mid; k++)
     if (sign[i-1][k])
     {
      sign[i][k + wet[i]*len[j]] += sign[i-1][k];    
     }
     cout<< sign[G][Mid]<<endl;
     return 0;
}

posted on 2011-05-06 18:42  _Clarence  阅读(192)  评论(0编辑  收藏  举报

导航