《挑战程序设计竞赛(五)》背包问题2:大规模质量化

题目:P60
按照书中所给思路,我完成了如下代码

#include 
#include
#include
#define MAXN 100
#define MAXV 100
#define INF 999

using namespace std;
int dp[MAXN][MAXN];
int sets[MAXN][2];
void Package(int W,int n)
{
	for (int i = 0;i <n;i++)
	{
		for (int j = 0;j <=MAXN*MAXV+1;j++)
		{
			if (j<sets[i][1])
			{
				dp[i + 1][j] = dp[i][j];
			}
			else
			{
				dp[i + 1][j] = min(dp[i][j], dp[i][j - sets[i][1] ]+ sets[i][0]);
			}
		}
	}
}
int main()
{
	int n, W;
	//初始化n
	cin >> n;
	//初始化{w,v}
	for (int i = 0;i <n;i++)
	{
		for (int j = 0;j < 2;j++)
		{
			cin >> sets[i][j];
		}
	}
	//初始化W
	cin >> W;
	fill(dp[0], dp[0] + MAXN*MAXV+1, INF);
	putchar('H'); 
	Package(W,n);
	putchar('H'); 
	int res = 0;
	for (int i = 0;i <= n;n++)
	{
		if (dp[n][i] < W)
		{
			res = dp[n][i];
		}
	}

	printf("\n%d",res);
	getchar();
	getchar();
}

不幸的是,运行结果为:

4
2 3
1 2
3 4
2 2
5
HH
0

从人为设置的“原始断点”来看,这意味着函数Pakage运行完毕后,任然没能达到目标结果……
(我好菜……)

为了检验是否是输入的问题,设置“测试代码”:

for (int i = 0;i <n;i++)
	{
		for (int j = 0;j < 2;j++)
		{
			cout << sets[i][j];
			printf("\t");
		}
		printf("\n");
	}

输出正常:

2       3
1       2
3       4
2       2

挨个测试了W,n都没有问题

那么,极有可能是错在函数上了

照着书上的改了一下,发现初始化和数组大小的推理上弄错了,就改为:

#include 
#include
#include
#define MAXN 100
#define MAXV 100
#define INF 999

using namespace std;
int dp[MAXN+1][MAXN*MAXV+1];
int sets[MAXN][2];
void Package(int W,int n)
{
	for (int i = 0;i <n;i++)
	{
		for (int j = 0;j <= MAXN*MAXV;j++)
		{
			if (j<sets[i][1])
			{
				dp[i + 1][j] = dp[i][j];
			}
			else
			{
				dp[i + 1][j] = min(dp[i][j], dp[i][j - sets[i][1]] + sets[i][0]);
			}
		}
	}
}
int main()
{
	int n, W;
	//初始化n
	cin >> n;
	//初始化{w,v}
	for (int i = 0;i <n;i++)
	{
		for (int j = 0;j < 2;j++)
		{
			cin >> sets[i][j];
		}
	}
	//初始化W
	cin >> W;
	fill(dp[0], dp[0] + MAXN*MAXV+1, INF);
	dp[0][0]=0;
	Package(W,n);
	int res = 0;
	for (int i = 0;i <= MAXN*MAXV;i++)
	{
		if (dp[n][i] < W)
		{
			res = dp[n][i];
		}
	}
	cout << res;
	getchar();
	getchar();
}

运行结果为4

痛定思痛,我觉得自己可能是理解错算法的思想了

就反思了一下,发现目标是要:
1.先求n项物资在价值一定的情况下的最小重量
2.然后在重量小于限制得情况下求出最大价值

我显然把重量当做价值输出了,emmm……
修改后的代码如下

#include 
#include
#include
#define MAXN 100
#define MAXV 100
#define INF 999

using namespace std;
int dp[MAXN+1][MAXN*MAXV+1];
int sets[MAXN][2];
void Package(int W,int n)
{
	for (int i = 0;i <n;i++)
	{
		for (int j = 0;j <= MAXN*MAXV;j++)
		{
			if (j<sets[i][1])
			{
				dp[i + 1][j] = dp[i][j];
			}
			else
			{
				dp[i + 1][j] = min(dp[i][j], dp[i][j - sets[i][1]] + sets[i][0]);
			}
		}
	}
}
int main()
{
	int n, W;
	//初始化n
	cin >> n;
	//初始化{w,v}
	for (int i = 0;i <n;i++)
	{
		for (int j = 0;j < 2;j++)
		{
			cin >> sets[i][j];
		}
	}
	//初始化W
	cin >> W;
	fill(dp[0], dp[0] + MAXN*MAXV+1, INF);
	dp[0][0]=0;
	Package(W,n);
	int res = 0;
	for (int i = 0;i <= MAXN*MAXV;i++)
	{
		if (dp[n][i] <= W)
		{
			res = i;
		}
	}
	cout << res;
	getchar();
	getchar();
}

样例通过,为7

YES

我好菜啊……

反思与总结:
1、要设置断点来找错
2、优先考虑是不是思路错了

希望能有所帮助

你可能感兴趣的:(《挑战程序设计竞赛(五)》背包问题2:大规模质量化)