P1060 [NOIP2006 普及组] 开心的金明
状态f[i][j]
表示前i
件物品使用j
元可以得到的物品价格c[i] * 物品重要度w[i]
最大值,f[m][n]
即本题的解
求f[i][j]
:
- 如果不购买第
i
件物品,f[i][j] = f[i - 1][j]
- 如果购买第
i
件物品,f[i][j] = f[i - 1][j - c[i]] + c[i] * w[i]
边界条件:
f[i][j] = 0 (i == 0 || j == 0)
#include<bits/stdc++.h>
using namespace::std;
int f[30][30005], w[30],c[30], N, V;
void ZeroOnePack()
{
for(int i = 0; i <= N; ++i)
f[i][0] = 0;
for(int i = 0; i <= V; ++i)
f[0][i] = 0;
for(int i = 1; i <= N; ++i)
{
for(int j = 1; j <= V; ++j)
{
if(j >= c[i])
f[i][j] = max(f[i - 1][j], f[i - 1][j - c[i]] + c[i] * w[i]);
else
f[i][j] = f[i - 1][j];
}
}
}
int main()
{
cin >> V >> N;
for(int i = 1; i <= N; ++i)
{
cin >> c[i] >> w[i];
}
ZeroOnePack();
cout << f[N][V];
return 0;
}
降维简化
#include<bits/stdc++.h>
using namespace::std;
int f[30005], w[30],c[30], N, V;
void ZeroOnePack()
{
for(int i = 1; i <= N; ++i)
for(int j = V; j >= c[i]; --j)
f[j] = max(f[j], f[j - c[i]] + c[i] * w[i]);
}
int main()
{
cin >> V >> N;
for(int i = 1; i <= N; ++i)
{
cin >> c[i] >> w[i];
}
ZeroOnePack();
cout << f[V];
return 0;
}