首页 > 其他分享 >P1510 精卫填海

P1510 精卫填海

时间:2023-11-03 11:13:57浏览次数:37  
标签:精卫填海 min int P1510 零到 include

P1510 精卫填海

最初思路

状态方程F[i]i是体积,F[i]指能填平该体积的最小体力。

推出转移方程F[i] = min(F[i], F[i-v[i]] + m[i])

但是代码实现只有10pts

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int v, n, c;
int k[10010], m[10010];
int F[100100];

int main() {
	cin >> v >> n >> c;
	for (int i = 1; i <= n; i++) {
		cin >> k[i] >> m[i];
	}
	for (int i = 1; i <= v + 5000; i++) {
		F[i] = 0x3f3f3f;
	}
	for (int i = 1; i <= n; i++) {
		for (int j = v; j >= k[i]; j--) {
			F[j] = min(F[j], F[j - k[i]] + m[i]);
		}
	}
	if (c - F[v] >= 0)
		cout << c - F[v];
	else
		cout << "Impossible";
	return 0;
}

思路改进

如果是按照\(01\)背包,这层for循环枚举到k[i]是没问题的

for (int j = v; j >= k[i]; j--) 
{
	F[j] = min(F[j], F[j - k[i]] + m[i]);
}

但是这是一个求最小值的问题,01背包不需要枚举\(j\)从零到\(k[i]\)的值是因为这些值本该为0,已经被提前初始化好了。

而求最小值的话,\(j\)从零到\(k[i]\)时要等于说要装填一个小于当前物品体积的东西,那只能取当前物品的体力值,毕竟没有比当前物品体积小的东西了,所以应加上\(j\)从零到\(k[i]\)的处理

for (int i = 1; i <= n; i++) 
{
		for (int j = v; j >= 0; j--) 
        {
			if (j >= k[i])
				F[j] = min(F[j], F[j - k[i]] + m[i]);
			else
				F[j] = min(F[j], m[i]);
		}
	}

标签:精卫填海,min,int,P1510,零到,include
From: https://www.cnblogs.com/kdlyh/p/17807142.html

相关文章

  • P1510 精卫填海
    东海未填平的区域还需要至少体积为v的木石才可以填平,而西山上的木石还剩下n块,每块的体积和把它衔到东海需要的体力分别为k和m。精卫已经填海填了这么长时间了,她也很累了,她还剩下的体力为c。如果精卫能把东海填平,则输出她把东海填平后剩下的最大的体力,否则输出Impossibl......