数据很小,可以DFS,判断的时候用背包DP
然而不知到枚举到哪里。。。。
首先枚举前可以求一遍题目中的MAX,下一层DFS的时候可以只枚举到MAX + 1,因为再往上就必定会出现断层
蒟蒻很菜,人为规定背包上界。。。。
然后可以A
代码
#include <cstdio> #include <cstring> #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) int n, k, ans; int f[351], a[351], anslist[301]; bool b[106]; inline int check() { int i, j, cnt = 0; for(i = 1; i <= 101; i++) if(b[i]) a[++cnt] = i; memset(f, 127 / 3, sizeof(f)); f[0] = 0; for(i = 1; i <= k; i++) for(j = a[i]; j <= 350; j++) f[j] = min(f[j], f[j - a[i]] + 1); for(i = 1; i <= 350; i++) if(f[i] > n) { if(ans < i - 1) { ans = i - 1; for(j = 1; j <= k; j++) anslist[j] = a[j]; } break; } return i - 1; } inline void dfs(int p, int j, int up) { if(p > k) return; int i, u; for(i = j + 1; i <= up + 1; i++) if(!b[i]) { b[i] = 1; u = check(); dfs(p + 1, i, u); b[i] = 0; } } int main() { int i; scanf("%d %d", &n, &k); b[1] = 1; dfs(2, 1, n); for(i = 1; i <= k; i++) printf("%d ", anslist[i]); printf(" MAX=%d ", ans); return 0; }