题目大意:有N类物品,要求每类物品至少买一个,问能得到的最大价值是多少
解题思路:可以用二维DP解决,只能能转化的就转化取最大值
注意:价值和花费有可能为0,所以写的时候要注意顺序
正常二维数组
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int n, m, k;
int num[12], val[12][100], cost[12][100];
int dp[12][N];
void init() {
memset(num, 0, sizeof(num));
int a, b, c;
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &a, &b, &c);
cost[a][num[a]] = b;
val[a][num[a]] = c;
num[a]++;
}
}
void solve() {
memset(dp, -1, sizeof(dp));
for (int i = 0; i <= m; i++)
dp[0][i] = 0;
for (int set = 1; set <= k; set++) {
for (int i = 0; i < num[set]; i++) {
for (int j = m; j >= cost[set][i]; j--) {
if (dp[set][j - cost[set][i]] != -1)
dp[set][j] = max(dp[set][j], dp[set][j - cost[set][i]] + val[set][i]);
if (dp[set-1][j - cost[set][i]] != -1)
dp[set][j] = max(dp[set][j], dp[set-1][j - cost[set][i]] + val[set][i]);
}
}
}
if (dp[k][m] < 0) printf("Impossible\n");
else printf("%d\n", dp[k][m]);
}
int main() {
while (scanf("%d%d%d", &n, &m, &k) != EOF) {
init();
solve();
}
return 0;
}
滚动数组
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int n, m, k;
int num[12], val[12][110], cost[12][110];
int dp[2][N];
void init() {
memset(num, 0, sizeof(num));
int a, b, c;
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &a, &b, &c);
cost[a][num[a]] = b;
val[a][num[a]] = c;
num[a]++;
}
}
void solve() {
memset(dp, -1, sizeof(dp));
dp[0][0] = 0;
bool flag = false;
for (int i = 0; i < num[1]; i++) {
if (cost[1][i] == 0) flag = true;
for (int j = m; j >= cost[1][i]; j--)
if (dp[0][j - cost[1][i]] != -1) {
dp[0][j] = max(dp[0][j], dp[0][j - cost[1][i]] + val[1][i]);
}
}
if (!flag) dp[0][0] = -1;
for (int set = 2; set <= k; set++) {
memset(dp[1], -1, sizeof(dp[1]));
for (int i = 0; i < num[set]; i++)
for (int j = m; j >= cost[set][i]; j--) {
if (dp[1][j - cost[set][i]] != -1)
dp[1][j] = max(dp[1][j], dp[1][j - cost[set][i]] + val[set][i]);
if (dp[0][j - cost[set][i]] != -1)
dp[1][j] = max(dp[1][j], dp[0][j - cost[set][i]] + val[set][i]);
}
for (int i = 0; i <= m; i++)
dp[0][i] = dp[1][i];
}
int ans = -1;
for (int i = 0; i <= m; i++)
ans = max(dp[0][i], ans);
if (ans == -1) printf("Impossible\n");
else printf("%d\n", ans);
}
int main() {
while (scanf("%d%d%d", &n, &m, &k) != EOF) {
init();
solve();
}
return 0;
}