大一集训 背包
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }

浙公网安备 33010602011771号