Codeforces 687C. The Values You Can Make (dp)
题目链接:http://codeforces.com/problemset/problem/687/C
题目大概说给n个各有价值的硬币,要从它们中选出若干个组合成面值k,而要求的是各个方案里这些选出的硬币能组合出来的面值有哪些。
dp[i][j][k]表示到第i个硬币,组成面值为j,包含面值为k的方案数。
注意用滚动数组写。
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL; 15 typedef pair <int, int> P; 16 const int N = 505; 17 int dp[2][N][N], a[N]; 18 19 int main() 20 { 21 int n, k; 22 scanf("%d %d", &n, &k); 23 for(int i = 1; i <= n; ++i) { 24 scanf("%d", a + i); 25 } 26 dp[0][0][0] = 1; 27 for(int i = 1; i <= n; ++i) { 28 for(int j = k; j >= 0; --j) { 29 for(int x = j; x >= 0; --x) { 30 //memset(dp[i%2], 0, sizeof(dp[i%2])); 31 dp[i%2][j][x] |= dp[(i - 1)%2][j][x]; //滚动数组重复使用 32 if(j - a[i] >= x) 33 dp[i%2][j][x] |= dp[(i - 1)%2][j - a[i]][x]; 34 if(x >= a[i]) 35 dp[i%2][j][x] |= dp[(i - 1)%2][j - a[i]][x - a[i]]; 36 } 37 } 38 } 39 int cnt = 0, ans[505]; 40 for(int i = 0; i <= k; ++i) { 41 if(dp[1][k][i] || dp[0][k][i]) { 42 ans[++cnt] = i; 43 } 44 } 45 printf("%d\n", cnt); 46 for(int i = 1; i <= cnt; ++i) { 47 printf("%d%c", ans[i], i == cnt ? '\n': ' '); 48 } 49 return 0; 50 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步