1.装箱问题(NOIP2001普及组)
http://codevs.cn/problem/1014/
方程:
重复背包模型f[j] = max(f[j], f[j - w[i]] + w[i])
(0<=j<=v, 1<=i<=n, j>=w[i])
代码:
#include<bits/stdc++.h>
int f[20001];
int main()
{
int v, n;
int w[31];
scanf("%d%d", &v, &n);
for (int i = 1; i <= n; i++)
scanf("%d", &w[i]);
int ans = 0;
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; i++)
for (int j = v; j >= w[i]; j--)
f[j] = max(f[j], f[j - w[i]] + w[i]);
printf("%d\n", v - f[v]);
return 0;
}
2.乌龟棋(NOIP2010提高组)
http://codevs.cn/problem/1068/
方程:
f[a][b][c][d]=max{(a>0)f[a-1][b][c][d], (b>0)f[a][b-1][c][d], (c>0)f[a][b][c-1][d], (d>0)f[a][b][c][d-1]} + w[a*1+b*2+c*3+d*4]
(a,b,c,d描述四种卡片的张数)
代码:
#include <bits/stdc++.h>
#define MAX_N 351
#define MAX_M 41
using namespace std;
int f[MAX_M][MAX_M][MAX_M][MAX_M];
int main()
{
int n, m;
int a[MAX_N];
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> a[i];
int num, s1 = 0, s2 = 0, s3 = 0, s4 = 0;
for (int i = 0; i < m; i++)
{
cin >> num;
if (num == 1) s1++;
if (num == 2) s2++;
if (num == 3) s3++;
if (num == 4) s4++;
}
for (int i = 0; i <= s1; i++)
for (int j = 0; j <= s2; j++)
for (int k = 0; k <= s3; k++)
for (int l = 0; l <= s4; l++)
{
f[i][j][k][l] = 0;
if (i != 0) f[i][j][k][l] = max(f[i][j][k][l], f[i-1][j][k][l]);
if (j != 0) f[i][j][k][l] = max(f[i][j][k][l], f[i][j-1][k][l]);
if (k != 0) f[i][j][k][l] = max(f[i][j][k][l], f[i][j][k-1][l]);
if (l != 0) f[i][j][k][l] = max(f[i][j][k][l], f[i][j][k][l-1]);
f[i][j][k][l] += a[i + j*2 + k*3 + l*4];
}
cout << f[s1][s2][s3][s4];
return 0;
}