01背包的搜索原理(还是懵逼)

P1802 5倍经验日
背包还是理解不到位呀QWQ
思路
简单的01背包,不过实在01背包的基础上加了一个小小的变化,也就是不用药打也是要算在重量内。

所以可得动态转移方程:

f[j]=max(f[j]+lost[i],f[j-use[i]]+win[i]) (当j>=use[i]时)

f[j]=f[j]+lost[i] (当j<use[i]时)//重点

注意:
由于有时取不到赢的价值,但一定能取到输的价值,所以循环一定要循环到0,然后判断能否取赢的。举个简单的例子,如果他用药数比x还大,那么循环到wi就肯定跳过了,而输的价值就被吃了

错误题解

#include<bits/stdc++.h>
using namespace std;
long long f[1010];
int main()
{
	int n, x;
	long long lose[1010], win[1010], use[1010];
	cin>>n>>x;
	for(int i = 1; i <= n; i++)
	cin>>lose[i]>>win[i]>>use[i];
	
	for(int i = 1; i <= n; i++)
		for(int j = x; j >= use[i]; j--)
	    {
		    f[j] = max (f[j] + lose[i], f[j - use[i]] + win[i]); 
		
	    }
	
	cout<<f[x] * 5<<endl;
	
}

正确题解


#include<bits/stdc++.h>
using namespace std;
long long f[1010];
int main()
{
	int n, x;
	long long lose[1010], win[1010], use[1010];
	cin>>n>>x;
	for(int i = 1; i <= n; i++)
	cin>>lose[i]>>win[i]>>use[i];
	
	for(int i = 1; i <= n; i++)
	{
		for(int j = x; j >= use[i]; j--)
	    {
		    f[j] = max (f[j] + lose[i], f[j - use[i]] + win[i]); 
		
	    }
	    for(int j = use[i] - 1; j >= 0; j--)  // 保证至少取到输的价值
	    f[j] += lose[i];
	}
	
	cout<<f[x] * 5<<endl;
	
}

P2347 砝码称重
题解
没什么好说的,背包套路

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a[10] = {1, 2, 3, 5, 10, 20};
    int x, index = 0;
    int cnt[1005], f[1005];
    memset(f, 0,sizeof(f));
    for(int i = 0; i < 6; i++)
    {
    	cin>>x;
    	while(x--) cnt[++index] = a[i];
    	
	}
	f[0] = 1;
	for(int i = 1; i <= index; i++)
	for(int j = 1000; j >= 0; j--)
	{
		if(f[j] == 1) f[j + cnt[i]] = 1;
	}
	for(int i = 2; i<= 1000; i++)
    f[i] +=f[i - 1];
	cout<<"Total="<<f[1000]<<endl;
    
    
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值