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; }