题目链接点这儿
大意就是给出好多物品(测试后得出1000以内的super prime只有201个),每个物品不限个数。让你判断某个容量的背包可不可以正好装满,如果可以装满的话,给出最优的解,就是物品个数最少的解。
很简单的完全背包,不需要二进制压缩,也不用考虑容量。直接写个裸的就可以过。super prime偷懒直接打表了。
第一次wa了,因为没看到最优解。。以为是随便一组解就可以了。
下面放出代码。
#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(i,initial_n,end_n) for(int (i)=(initial_n);(i)<(end_n);i++)
#define repp(i,initial_n,end_n) for(int (i)=(initial_n);(i)<=(end_n);(i)++)
#define reep(i,initial_n,end_n) for((i)=(initial_n);(i)<(end_n);i++)
#define reepp(i,initial_n,end_n) for((i)=(initial_n);(i)<=(end_n);(i)++)
#define eps 1.0e-9
#define MAX_N 1010
using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef long long ll;
typedef unsigned long long ull;
int super[220] = { 3, 5, 11, 17, 31, 41, 59, 67, 83, 109, 127, 157, 179, 191, 211, 241, 277, 283, 331, 353, 367, 401, 431, 461, 509, 547, 563, 587, 599, 617, 709, 739, 773, 797, 859, 877, 919, 967, 991, 1031, 1063, 1087, 1153, 1171, 1201, 1217, 1297, 1409, 1433, 1447, 1471, 1499, 1523, 1597, 1621, 1669, 1723, 1741, 1787, 1823, 1847, 1913, 2027, 2063, 2081, 2099, 2221, 2269, 2341, 2351, 2381, 2417, 2477, 2549, 2609, 2647, 2683, 2719, 2749, 2803, 2897, 2909, 3001, 3019, 3067, 3109, 3169, 3229, 3259, 3299, 3319, 3407, 3469, 3517, 3559, 3593, 3637, 3733, 3761, 3911, 3943, 4027, 4091, 4133, 4153, 4217, 4273, 4339, 4397, 4421, 4463, 4517, 4549, 4567, 4663, 4759, 4787, 4801, 4877, 4933, 4943, 5021, 5059, 5107, 5189, 5281, 5381, 5441, 5503, 5557, 5623, 5651, 5701, 5749, 5801, 5851, 5869, 6037, 6113, 6217, 6229, 6311, 6323, 6353, 6361, 6469, 6599, 6653, 6661, 6691, 6823, 6841, 6863, 6899, 7057, 7109, 7193, 7283, 7351, 7417, 7481, 7523, 7607, 7649, 7699, 7753, 7841, 7883, 8011, 8059, 8101, 8117, 8221, 8233, 8287, 8377, 8389, 8513, 8527, 8581, 8719, 8747, 8761, 8807, 8849, 8923, 8999, 9041, 9103, 9293, 9319, 9403, 9461, 9539, 9619, 9661, 9739, 9833, 9859, 9923, 9973 };
int pre[10010], dp[10010];
int main() {
int n;
scanf("%d", &n);
fill(dp, dp + n + 1, INT_MAX);
dp[0] = 0, pre[0] = -1;
repp(i, 0, n) {
for(int j = 0; j < 201 && i+super[j] <= n; j++) {
if(dp[i] < INT_MAX && dp[i+super[j]] > dp[i] + 1) {
dp[i+super[j]] = dp[i] + 1;
pre[i+super[j]] = i;
}
}
}
if(dp[n] != INT_MAX) {
printf("%d\n", dp[n]);
while(n) {
printf("%d ", n - pre[n]);
n = pre[n];
}
}
else puts("0");
return 0;
}