pku 1837 Balance(DP)

题意:一个杠杆,中心有支点,两边有挂钩,挂钩位置由输入给定。有一些砝码,砝码重量由输入给定。一个挂钩下可以挂多个砝码,也可以什么都不挂,但每个砝码必须都用。问有多少种组合方式,可以使杠杆平衡。

 

做这题,切身体会到了 DP才是王道 这话的含义。

初看题目,穷举。看DISCUSS,原来是DP。

像这种组合方式很多,但状态空间却不大的,一般都可以交给DP。

 

DP[i][j]表示放置第i个物品后,总质量为j的可能组合的数量。

状态转移方程 DP[i+1][j]=sum{DP[i][j-weight[i]*hook[k]](1<=k<=C)}

初始化 DP[0][0]=1,最后输出 DP[G][0].

因为DP[i][j]中j可能为负数,在代码中给j加上一个偏移量base。

 

#include <iostream> using namespace std; const int base=6000; int DP[21][base+base]; int hook[20],weight[20]; int main() { memset(DP,0,sizeof(DP)); int C,G; scanf("%d%d",&C,&G); for(int i=0;i<C;i++) { scanf("%d",&hook[i]); } for(int i=0;i<G;i++) { scanf("%d",&weight[i]); } DP[0][0+base]=1; for(int i=1;i<=G;i++) { for(int j=-4000+base;j<4000+base;j++) { for(int k=0;k<C;k++) { DP[i][j]+=DP[i-1][j-hook[k]*weight[i-1]]; } } } printf("%d/n",DP[G][0+base]); return 0; }

你可能感兴趣的:(pku 1837 Balance(DP))