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;
}
浙公网安备 33010602011771号