背包dp(完全)

http://poj.org/problem?id=3181

高精+背包

完全背包求方案数则只需dp[ j ] + = dp[ j - w[ i ] ]即可;任意一种背包方案计算都只需将max变为+;

这道题要注意,求方案数一般有很多,不mod,就自己看看数据是否超内存;

dp[ i ]存放前18位;dp[ i ]存放后18位;

对于前18位 dp[ j ]= dp[ j ] + dp [ j-w[ i ] ] + ( dp1[ j ]+dp1[ j-w[ i ] ) / inf

 前18位相加,在加上后18位相加时产生的进位;

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 #define int long long
 5 const int maxn=1100;
 6 __int64 inf=1;
 7 int dp[maxn],dp1[maxn];
 8 signed main()
 9 {
10     int n,k;
11     cin>>n>>k;
12     memset(dp,0,sizeof(dp));
13     memset(dp1,0,sizeof(dp1));
14     for (int i=0; i<18; i++)    inf *= 10;
15     dp1[0]=1;
16     for(int i=1;i<=k;i++)
17     {
18         for(int j=i;j<=n;j++)
19         {
20             dp[j]=dp[j]+dp[j-i]+(dp1[j]+dp1[j-i])/inf;
21             dp1[j]=(dp1[j]+dp1[j-i])%inf;
22         }
23     }
24    if(dp[n]) cout<<dp[n];
25     cout<<dp1[n]<<endl;
26 }
View Code

 Hdu 1114 Piggy-Bank

完全背包模板题;

适合深刻理解装满状态;

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int inf=0x3f3f3f3f;
 4 const int maxn=10010;
 5 int dp[maxn],n,m,e,f,val[maxn],w[maxn];
 6 signed main()
 7 {
 8     cin>>n;
 9     while(n--)
10     {
11         scanf("%d %d",&e,&f);
12         scanf("%d",&m);
13         for(int i=1;i<=m;i++)
14         {
15             scanf("%d %d",&val[i],&w[i]);
16         }
17         memset(dp,inf,sizeof(dp));
18         dp[0]=0;
19         for(int i=1;i<=m;i++)
20         {
21             for(int j=w[i];j<=f-e;j++)
22             {
23                 dp[j]=min(dp[j],dp[j-w[i]]+val[i]);
24             }
25         }
26         if(dp[f-e]==inf) printf("This is impossible.\n");
27         else printf("The minimum amount of money in the piggy-bank is %d.\n",dp[f-e]);
28     }
29 }
View Code

 

posted @ 2020-07-04 23:36  SuccessfulRoad  阅读(138)  评论(0编辑  收藏  举报