01背包问题变形
#include<iostream>
using namespace std;
#define LL long long
const int N = 1010;
int win[N], lose[N], use[N];
int f[N][N];
int n, x;
int main(){
cin >> n >> x;
for(int i = 1; i <= n; i ++) cin >> lose[i] >> win[i] >> use[i];
for(int i = 1; i <= n; i ++)
for(int j = 0; j <= x; j ++){
f[i][j] = f[i - 1][j] + lose[i];
if(j >= use[i]) f[i][j] = max(f[i][j], f[i - 1][j - use[i]] + win[i]);
}
cout << (LL) f[n][x] * 5 << endl;
return 0;
}
将状态转移矩阵改为1维的时候,出现问题
错代码:
#include<iostream>
using namespace std;
#define LL long long
const int N = 1010;
int win[N], lose[N], use[N];
int f[N];
int n, x;
int main(){
cin >> n >> x;
for(int i = 1; i <= n; i ++) cin >> lose[i] >> win[i] >> use[i];
for(int i = 1; i <= n; i ++){
for(int j = x; j >= 0; j --){
f[j] += lose[i];
if(j >= use[i]) f[j] = max(f[j], f[j - use[i]] + win[i]);
}
}
cout << (LL) f[x] * 5 << endl;
return 0;
}
错在这个地方:
f[j] += lose[i];
if(j >= use[i]) f[j] = max(f[j], f[j - use[i]] + win[i]);
这个地方对于use[i] != 0没有问题,但是对于use[i] = 0的情况必错,因为当use[i] = 0时,先将原本的f[j] += lose[i], 当j >= 0时,f[j] = max(f[j], f[j] + win[i]);此处f[j]必被更新为f[j] + win[i], 即被更新成原本的f[j] + win[i] + lose[i], 显然错。
正确代码:
#include<iostream>
using namespace std;
#define LL long long
const int N = 1010;
int win[N], lose[N], use[N];
int f[N];
int n, x;
int main(){
cin >> n >> x;
for(int i = 1; i <= n; i ++) cin >> lose[i] >> win[i] >> use[i];
for(int i = 1; i <= n; i ++){
for(int j = x; j >= 0; j --){
if(j < use[i]){
f[j] = f[j] + lose[i];
continue;
}
f[j] = max(f[j] + lose[i], f[j - use[i]] + win[i]);
}
}
cout << (LL) f[x] * 5 << endl;
return 0;
}