首页 > 代码库 > 背包训练

背包训练

1. HDU 2546 01背包

问题分析:

  a) 若饭卡钱数小于5则结果为:饭卡钱数。否则找出若干菜品的价格和(不包括最大价格菜品)最趋于饭卡价格-5,最大价格菜品留着最后减去(这样才能使得最终饭卡钱数最少)。

  b) 饭卡钱数-5 为背包容量,找出最大价格菜品(这里用sort排序,最后一个为最大价格),一直装入背包。结果为:饭卡钱数-最大价格-dp[饭卡钱数-5]

  dp[i] 表示:容量为 i 时 所拥有的最大钱数。在该题中表示 当钱数为 i 时 最接近 i 钱数的钱数。

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int dp[10000+6],a[1005];
 4 int main()
 5 {
 6     int n,m;
 7     while(scanf("%d",&n)!=EOF&&n)
 8     {
 9         memset(dp,0,sizeof(dp));
10         memset(a,0,sizeof(a));
11         for(int i=0; i<n; i++)
12             scanf("%d",&a[i]);
13         scanf("%d",&m);
14         sort(a,a+n);
15         for(int i=0; i<n-1; i++)
16             for(int j=m-5; j>=a[i]; j--)
17                 dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
18         if(m<5)
19             printf("%d\n",m);
20         else
21             printf("%d\n",m-dp[m-5]-a[n-1]);
22     }
23     return 0;
24 }
View Code

 2. HDU 1114 完全背包

问题分析:

  最终要使得 放入的钱的重量==放钱后的重量-空罐的重量时 钱数最小。

  dp[i] 表示:容量为 i 时 所拥有的最小钱数。在该题中表示 当容量为 钱的重量(=放钱后的重量-空罐的重量)时最少价值。

  注意在初始化时 dp[0]=0,没有重量即没有价值。

技术分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int dp[10000+6],v[505],w[505];
 4 int main()
 5 {
 6     int T,s,e,tn,i,j;
 7     scanf("%d",&T);
 8     while(T--)
 9     {
10         memset(v,0,sizeof(v));
11         memset(w,0,sizeof(w));
12         scanf("%d%d%d",&s,&e,&tn);
13         for(i=0; i<e; ++i)
14             dp[i]=1<<30;
15         dp[0]=0;
16         for(i=1; i<=tn; ++i)
17             scanf("%d%d",&v[i],&w[i]);
18         for(i=1; i<=tn; ++i)
19             for(j=w[i]; j<=e-s; ++j)
20                 dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
21         if(dp[e-s]==1<<30)
22             printf("This is impossible.\n");
23         else
24             printf("The minimum amount of money in the piggy-bank is %d.\n",dp[e-s]);
25     }
26     return 0;
27 }
View Code

 

背包训练