大一集训 背包

A - Bone Collector HDU - 2602  背包水题

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int main()
 5 {
 6     int t,n,v;
 7     scanf("%d", &t);
 8     while (t--) {
 9         scanf("%d %d", &n, &v);
10         int c[1010], w[1010], f[1010] = {0};
11         for (int i = 1;i <= n;++i)scanf("%d", w + i);
12         for (int i = 1;i <= n;++i)scanf("%d", c + i);
13         for (int i = 1;i <= n;i++) {
14             for (int j = v;j >= c[i];j--) {
15                 f[j] = max(f[j],f[j - c[i]] + w[i]);
16             }
17         }
18         printf("%d\n", f[v]);
19     }
20     return 0;
21 }
View Code

B - 饭卡 HDU - 2546 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<map>
 6 #include<vector>
 7 #include<set>
 8 #include<string>
 9 #include<cmath>
10 #include<cstring>
11 #define INF 0x3f3f3f3f3f3f3f3f
12 #define maxn 1010
13 using namespace std;
14 int main()
15 {
16     int n;
17     while (scanf("%d", &n),n) {
18         int value[maxn];
19         for (int i = 1;i <= n;i++) {
20             scanf("%d", &value[i]);
21         }
22         int m;
23         scanf("%d", &m);
24         if (m < 5) { printf("%d\n", m);continue; }
25         int dp[maxn]= {0};
26         sort(value + 1, value + 1 + n);
27         for (int i = 1;i < n;i++) {
28             for (int j = m - 5;j >= value[i];j--) {
29                 //if (value[i] <= j)
30                     dp[j] = max(dp[j], dp[j - value[i]] + value[i]);
31             }
32         }
33         printf("%d\n", m - dp[m - 5] - value[n]);
34     }
35     return 0;
36 }
View Code

C - 湫湫系列故事——减肥记I HDU - 4508   完全背包

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<map>
 6 #include<vector>
 7 #include<set>
 8 #include<string>
 9 #include<cmath>
10 #include<cstring>
11 #define INF 0x3f3f3f3f3f3f3f3f
12 #define maxn 100010
13 using namespace std;
14 int main()
15 {
16     int n;
17     while (scanf("%d", &n)!=EOF) {
18         int a[110], b[110];
19         for (int i = 1;i <= n;i++) {
20             scanf("%d %d", &a[i], &b[i]);
21         }
22         int m;
23         scanf("%d", &m);
24         int dp[maxn] = {0};
25         for (int i = 1;i <=n;i++) {
26             for (int j = b[i];j<=m;j++) {
27                 dp[j] = max(dp[j], dp[j - b[i]] + a[i]);
28             }
29         }
30         printf("%d\n", dp[m]);
31     }
32     return 0;
33 }
View Code

D - Coins hdu 2844

求可以组成多少种不同硬币价值?

 1 #include<iostream>
 2 #include<algorithm>
 3 #define inf 0x3f3f3f3f
 4 using namespace std;
 5 int main()
 6 {
 7     int n, m;
 8     while (scanf("%d %d", &n, &m), n + m) {
 9         int A[111], C[111];
10         for (int i = 1;i <= n;i++)scanf("%d", A + i);
11         for (int i = 1;i <= n;i++)scanf("%d", C + i);
12         int dp[100010] = {0};
13         int arr[100010] = {0};
14         for (int i = 1;i <= n;i++) {
15             for (int k = 1;C[i];k <<= 1) {
16                 k = min(k, C[i]);
17                 C[i] -= k;
18                 for (int j = m;j >= k * A[i];j--) {
19                     dp[j] =max(dp[j],dp[j - k * A[i]] + k * A[i]);
20                     arr[dp[j]] = 1;
21                 }
22             }
23         }
24         int ans=0;
25         for (int i = 1;i <= m;i++) {
26             if (arr[i]!=0)ans++;
27         }
28         printf("%d\n", ans);
29     }
30     return 0;
31 }
View Code

E - 寒冰王座 HDU - 1248

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<map>
 6 #include<vector>
 7 #include<set>
 8 #include<string>
 9 #include<cmath>
10 #include<cstring>
11 #define INF 0x3f3f3f3f3f3f3f3f
12 #define maxn 10010
13 using namespace std;
14 int main()
15 {
16     int t;
17     scanf("%d", &t);
18     while (t--) {
19         int n;
20         scanf("%d", &n);
21         int wd = n / 300;
22         int mfy = n / 200;
23         int xp = n / 150;
24         int left = 10000;
25         for (int i = wd;i >= 0;i--) {
26             for (int j = mfy;j >= 0;j--) {
27                 for (int k = xp;k >= 0;k--) {
28                     int ans = n - i * 300 - j * 200 - k * 150;
29                     if (ans >= 0 && ans < left)left = ans;
30                 }
31             }
32         }
33         printf("%d\n", left);
34     }
35     return 0;
36 }
View Code

F - ACboy needs your help hdu1712

题目大意:给你天数,在这几天中最大能获得多少幸福值。

例如:3 2 1,表示学习一天获得3,学习两天只获得2,学习三天获得1.学得越多获得的不一定越多。

 1 #include<iostream>
 2 #include<algorithm>
 3 #define inf 0x3f3f3f3f
 4 using namespace std;
 5 int main()
 6 {
 7     int n, m;
 8     while (scanf("%d %d", &n, &m), n + m) {
 9         int a[110][110];
10         for (int i = 1;i <= n;i++) {
11             for (int j = 1;j <= m;j++) {
12                 scanf("%d", &a[i][j]);
13             }
14         }
15         int dp[110] = {0};
16         for (int i = 1;i <= n;i++) {
17             for (int j = m;j >=1;j--) {
18                 for (int k = 1;k <= j;k++) {
19                     dp[j] = max(dp[j], dp[j - k] + a[i][k]);
20                 }
21             }
22         }
23         printf("%d\n", dp[m]);
24     }
25     return 0;
26 }
View Code

G - The Fewest Coins POJ3260

题意:农夫约翰要购买价格为T的物品,他有N种硬币,每种硬币的面额为Vi,数量为Ci,同时店主也只有这几种面额的硬币,但数量无限,问约翰总共要经手的硬币数量(约翰买东西给店主的硬币数量+店主找钱给约翰的硬币数量=约翰经手的硬币数量)(约翰是多重背包,店主是完全背包)
思路:我们用约翰所拥有的硬币总额来做背包容量是肯定不行的;
可以注意到,上界为w*w+m(w最大面额的纸币),也就是24400元。(网上的证明)证明如下:
如果买家的付款数大于了w*w+m,即付硬币的数目大于了w,根据鸽笼原理,至少有两个的和对w取模的值相等,也就是说,这部分硬币能够用更少的w来代替。(这个没懂)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #define inf 0x3f3f3f3f
 5 using namespace std;
 6 int dp1[30010], dp2[30010];
 7 int main()
 8 {
 9     int n, t;
10     scanf("%d %d", &n, &t);
11     int v[110], c[110];
12     int number = 0;
13     for (int i = 1;i <= n;i++) { scanf("%d", v + i); if (v[i] > number)number = v[i]; }
14     for (int i = 1;i <= n;i++)scanf("%d", c + i);
15     int T = t + number*number;
16     memset(dp1, inf, sizeof dp1);
17     memset(dp2, inf, sizeof dp2);
18     dp1[0] = 0,dp2[0]=0;
19     for (int i = 1;i <= n;i++) {
20         for (int k = 1;c[i];k <<= 1) {
21             k = min(k, c[i]);
22             c[i] -= k;
23             for (int j = T;j >= k * v[i];j--) {
24                 dp1[j] = min(dp1[j], dp1[j - k * v[i]] + k);
25             }
26         }
27     }
28     for (int i = 1;i <= n;i++) {
29         for (int j = v[i];j <= T;j++) {
30             dp2[j] = min(dp2[j], dp2[j - v[i]] + 1);
31         }
32     }
33     int ans = inf;
34     for (int i = t;i <= T;i++)ans = min(ans, dp1[i] + dp2[i - t]);
35     printf("%d\n", ans != inf ? ans : -1);
36     return 0;
37 }
View Code

H - https://ac.nowcoder.com/acm/contest/3405/C

 1 #include<cstdio>
 2 #include<vector>
 3 #include<stack>
 4 #include<set>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxn = 1e6 + 10;
 8 const int inf = 0x3f3f3f3f;
 9 int n, V, v[maxn], w[maxn], dp[maxn] = {0};
10 int main() {
11     scanf("%d%d", &n, &V);
12     int res = 0;
13     for (int i = 1;i <= n;i++)scanf("%d%d", v + i, w + i), res += w[i];
14     for (int i = 1;i <= n;i++) {
15         for (int j = res;j >= w[i];j--) {
16             dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
17         }
18     }
19     for (int i = 1;i <= res;i++) {
20         if (dp[i] >= V) {
21             printf("%d\n", i);
22             break;
23         }
24     }
25 }
View Code

 

posted @ 2020-02-08 13:51  programmer_w  阅读(1)  评论(0)    收藏  举报