标签:
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 11278 | Accepted: 7017 |
Description
Input
Output
Sample Input
2 4 -2 3 3 4 5 8
Sample Output
2
题意:在天平挂上所有的砝码,问使天平平衡的方案总数
思路:dp,首先定义平衡度:平衡时为0,倾向左为正,右为负,设挂完第i个砝码时平衡度为j的方案数为dp(i,j),
则dp(i,j)=dp(i-1,j-w[i]*x[1])+dp(i-1,j-w[i]*x[2])+...+dp(i-1,j-w[i]*x[C]);
边界限定:dp(0,0)=1; dp(0,j)=0 (j!=0)
所求解: dp(G,0)
记忆化搜索:
//47ms #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=30; const int INF=15010; int C,G;//C means the sum of hooks, G means the sum of weights int x[maxn],w[maxn]; int d[maxn][INF]; int zero=INF/2; int dp(int i,int j) { int &ans=d[i][j]; if(ans!=-1) return ans; if(i==0){ if(j==zero) return ans=1; return ans=0; } int sum=0; for(int k=1;k<=C;k++) sum+=dp(i-1,j-w[i]*x[k]); return ans=sum; } int main() { while(cin>>C>>G){ for(int i=1;i<=C;i++) cin>>x[i]; for(int i=1;i<=G;i++) cin>>w[i]; memset(d,-1,sizeof(d)); cout<<dp(G,zero)<<endl; } return 0; }
递推:
//110ms #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=30; const int INF=15010; const int zero=INF/2; int C,G; int w[maxn],x[maxn]; int dp[maxn][INF]; int main() { cin>>C>>G; for(int i=1;i<=C;i++) cin>>x[i]; for(int i=1;i<=G;i++) cin>>w[i]; memset(dp,0,sizeof(dp)); for(int i=0;i<INF;i++) dp[0][i]=0; dp[0][zero]=1; for(int i=1;i<=G;i++){ for(int j=0;j<INF;j++){ for(int k=1;k<=C;k++){ dp[i][j]+=dp[i-1][j-w[i]*x[k]]; } } } cout<<dp[G][zero]<<endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/--560/p/4341385.html