http://www.cnblogs.com/ziyi--caolu/p/3228090.html
http://blog.csdn.net/lyy289065406/article/details/6648094/
这道题更加理解了背包问题实质上是状态的转换。
范围中有负数,先平移到全是正数,因为最后所有砝码都要用上,所以可以先遍历第一个的所有情况,再以此推出第二个。
上面的思路用穷举是不行的,所以这时就要用DP,而背包正好很适合解决这一类问题,这就是解题的突破口
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <cctype> #include <vector> #include <iterator> #include <set> #include <map> #include <sstream> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define pf printf #define sf scanf #define spf sprintf #define pb push_back #define debug printf("!\n") #define MAXN 1010 #define MAX(a,b) a>b?a:b #define blank pf("\n") #define LL long long #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) #define pqueue priority_queue #define INF 0x3f3f3f3f int c,g; int dp[20][15000]; int cc[20],gg[20]; int main() { int i,j,k; while(~sf("%d%d",&c,&g)) { for(i=0;i<c;i++) { sf("%d",&cc[i]); } for(i=1;i<=g;i++) { sf("%d",&gg[i]); } dp[0][7500] = 1; for(i=1;i<=g;i++) { for(j=15000;j>=0;j--) { for(k=0;k<c;k++) { if(dp[i-1][j+cc[k]*gg[i]]>0) { dp[i][j]+= dp[i-1][j+cc[k]*gg[i]]; //pf("%d %d\n",i,j-7500); } } } } pf("%d\n",dp[g][7500]); } return 0; }
时间: 2024-11-08 14:33:50