杭电oj2602Bone Collector原题链接
题目描述:
思路:
01背包问题,当前最优解,要么包含第i种物品,要么不包含第i种物品。和物品顺序没有关系,不需要排序。
AC代码:
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int dp[1010][1010];
int c[1010],w[1010];
int main()
{
int T;
cin >> T;
int N,V;
while(T--)
{
cin >> N >> V;
for(int i = 1; i <= N;i++)
{
cin >> w[i];
}
for(int i = 1; i <= N; i++)
{
cin >> c[i];
}
memset(dp,0,sizeof(dp));//
for(int i = 1; i <= N; i++)
{
for(int j = 0; j <= V; j++)
{
if(j>=c[i])
{
dp[i][j] = max(dp[i-1][j], dp[i-1][j-c[i]] + w[i]);
}
else
{
dp[i][j] = dp[i-1][j];
}
}
}
cout << dp[N][V] << endl;
}
return 0;
}
代码优化:(空间复杂度简化为O(n))
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int dp[1010];
int c[1010],w[1010];
int main()
{
int T;
cin >> T;
int N,V;
while(T--)
{
cin >> N >> V;
for(int i = 1; i <= N;i++)
{
cin >> w[i];
}
for(int i = 1; i <= N;i++)
{
cin >> c[i];
}
memset(dp,0,sizeof(dp));
for(int i = 1; i <= N; i++)
{
for(int j = V; j >= c[i]; j--)//没必要循环到0,体积小于c[i]当前物品一定放不下
{
dp[j] = max(dp[j], dp[j-c[i]]+w[i]);
}
}
cout << dp[V] << endl;
}
return 0;
}