本文最后更新于:2023年9月12日 晚上
是我蠢了,这玩意官方有解析
注意事项 以下注意事项均针对csp中选择Dev-cpp(C++语言)条件
使用pow()
函数需要加上cmath
库否则编译错误,与在vs中仅添加iostream
有区别
二维数组声明时注意空格如vector<vector<int> >
,写为>>
出现编译错误
选择C++环境不支持auto智能指针
202209-1如此编码 根据提示完成即可,比较简单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> #include <vector> #include <fstream> using namespace std;int main () { ifstream cin ("aaa.txt" ) ; int n, m; cin >> n >> m; vector<int >a (n+1 ); for (int i = 1 ; i <= n; i++) cin >> a[i]; vector<int >c (n+1 ); vector<int >b (n+1 ); c[0 ] = 1 ; for (int i = 1 ; i <= n; i++) { c[i] = c[i - 1 ] * a[i]; b[i] = (m % c[i] - m % c[i - 1 ]) / c[i - 1 ]; } for (int i = 1 ; i <= n; i++) cout << b[i] << " " ; return 0 ; }
202209-2何以包邮 如果遍历所有的可能的取法,会有$2^{n}$种,运算量比较大,会有超时,只能拿下70分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> #include <vector> #include <cmath> using namespace std;int main () { int n, x; cin >> n >> x; vector<int > a (n) ; for (int i = 0 ; i < n; i++) cin >> a[i]; int res = INT_MAX; for (int i = pow (2 , n); i > 0 ; i--) { int sum = 0 ; for (int j = 0 ; j < n && (i >> j); j++) { if ((i >> j) & 1 ) { sum += a[j]; } } res = sum >= x ? min (sum, res) : res; } cout << res; }
考虑dfs+剪枝优化,同样是遍历,但通过计算节点后续能拿到的最大金额是否大于x,能够剪枝
但感觉还能用dp快速求解,类似于01背包,相当于把01背包问题的容量看做价格,用dp[j]表示价格不超过j的这n本书能组成的最大值,那么dp[j]=max(dp[j],dp[j-a[i]]+a[i])
,该解法满分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <vector> #include <iostream> using namespace std; int main () { int n, x,sum = 0 ; cin >> n >> x; vector<int >a (n); for (int i = 0 ; i < n; i++) { cin >> a[i]; sum += a[i]; } vector<int >dp (sum+1 ); for (int i = 0 ; i < n; i++) { for (int j = sum; j >= a[i]; j--) { if (j - a[i] >= 0 ) dp[j] = max (dp[j], dp[j - a[i]] + a[i]); } } for (int i = x; i <sum+1 ; i++) { if (dp[i] > x) { cout << dp[i]; return 0 ; } } }