Hdu 2602 Bone Collector

大意不再赘述。

思路:之所以再写一次这个题目是因为对这题有了更深的理解,而且找出了以前的一些BUG和理念上的错误,其中完全背包与0/1背包的区别,优化成滚动数组以及为什么可以优化成滚动数组,它的逆序循环,“阶段”的划分,而且在规划方向的选取上都有了较大的进步。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

const int MAXN = 1010;
const int INF = 0x3f3f3f3f;

int V[MAXN], W[MAXN];
int f[MAXN];
//int f[MAXN][MAXN];
int n, C;

void init()
{
	memset(f, 0, sizeof(f));
}

void read_case()
{
	scanf("%d%d", &n, &C);
	for(int i = 1; i <= n; i++) scanf("%d", &W[i]);
	for(int i = 1; i <= n; i++) scanf("%d", &V[i]);
}

void dp()
{
	init();
	for(int i = 1; i <= n; i++)
	for(int j = C; j >= 0; j--)
	{
		if(j >= V[i]) f[j] = max(f[j], f[j-V[i]]+W[i]); //滚动数组 
	}
}

/*void dp()
{
	init();
	for(int i = n; i >= 1; i--) //f[i][j]表示把第i,i+1...,n个物品装到容量为j的背包中的最大总重量。 
		for(int j = 0; j <= C; j++)
		{
			f[i][j] = f[i+1][j];
			if(j >= V[i]) f[i][j] = max(f[i][j], f[i+1][j-V[i]]+W[i]);
		}  //最好在里面加上 j >= V[i] 
}
*/

/*void dp()
{
	init();
	for(int i = 1; i <= n; i++) //对称的状态定义,表示把前i个物品装入容量为j的背包的最大容量 
		for(int j = C; j >= 0; j--)
		{
			f[i][j] = f[i-1][j]; //j可能小于V[i]
			if(j >= V[i]) f[i][j] = max(f[i-1][j], f[i-1][j-V[i]]+W[i]);
		}
}*/

void solve()
{
	read_case();
	dp();
	printf("%d\n", f[C]); //滚动数组不太好打印方案。 
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		solve();
	}
	return 0;
}


你可能感兴趣的:(Hdu 2602 Bone Collector)