每组数据给出m种得分方式,问做n个俯卧撑最多能得到多少分。
首先考虑只有得1分的,要做满5000个俯卧撑,最多是进行了100回合。所以极限也就只有100回合。于是进行动态规划,f[i][j]表示地 i 个回合,做 j 个俯卧撑,最多得到多少分,很容易就能推出后面的。最终答案就是max{f[i][n]}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5010;
const int maxm = 101;
int f[maxm][maxn], n, m, ans, a[20];
int init() {
ans = -1;
for (int i = 0; i <= 100; i++)
for (int j = 0; j <= n; j++) f[i][j] = -1;
f[0][0] = 0;
}
int main() {
freopen("input.txt","r",stdin);
int T;
scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &m);
init();
for (int i = 1; i <= m; i++) scanf("%d", &a[i]);
for (int i = 0; i <= 100; i++) {
for (int j = 0; j <= n; j++) if (f[i][j] >= 0) {
for (int k = 1; k <= m; k++) if (j+(i+1)*a[k] <= n) {
f[i+1][j+(i+1)*a[k]] = max(f[i+1][j+(i+1)*a[k]], f[i][j]+a[k]);
}
}
ans = max(ans, f[i][n]);
}
printf("%d\n", ans);
}
}