Week 8

        本周主要练习DP中的背包问题。

1.P1616 疯狂的采药 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:

        完全背包问题。

代码:

#include<cstdio>
#include<iostream>
using namespace std;
long long int t[10010],v[10010];
long long int res[10000010];
int main()
{
	long long int T,M;
	scanf("%lld%lld",&T,&M);
	for(int i=1;i<=M;++i)
		scanf("%lld%lld",&t[i],&v[i]);
	for(int i=1;i<=M;++i)
	{
		for(int j=t[i];j<=T;++j)
		{
			res[j]=max(res[j],res[j-t[i]]+v[i]);
		}
	}
	printf("%lld",res[T]);
	return 0;
}

2.P1833 樱花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:

        多重背包。将各种不同赏花都视为新情况,转化为01背包。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,T;
int w[100010],c[100010];
int f[100010];
int main()
{
	int h1,h2,m1,m2;
	scanf("%d:%d%d:%d%d",&h1,&m1,&h2,&m2,&n);
	T=(h2-h1-1)*60+m2+60-m1;
	int n1=0;
	for(int i=1;i<=n;++i)
	{
		int x,y,s,k=1;
		scanf("%d%d%d",&x,&y,&s);
		if(s==0) s=T/x;
		while(s>=k)
		{
			w[++n1]=x*k;c[n1]=y*k;
			s-=k;k*=2;
		}
		w[++n1]=s*x;c[n1]=s*y;
	}
	for(int i=1;i<=n1;++i)
	{
		for(int j=T;j>=w[i];--j)
			f[j]=max(f[j],f[j-w[i]]+c[i]);
	}
	printf("%d",f[T]);
	return 0;
}

3.P1077 [NOIP2012 普及组] 摆花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:

        同样转化为01背包。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int mod=1000007;
int n,m,a[110],f[110];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
    {
    	scanf("%d",&a[i]);
	}
	f[0]=1;
	for(int i=1;i<=n;++i)
	{
		for(int j=m;j>=0;--j)
		{
			int k=min(a[i],j);
			for(int p=1;p<=k;++p)
				f[j]=(f[j]+f[j-p])%mod;
		}
	}
	printf("%d",f[m]);
	
    return 0;
}

4.P1064 [NOIP2006 提高组] 金明的预算方案 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:

        将不同附件情况分开讨论。

代码: 

#include<iostream>
#include<cstdio>
using namespace std;
int m,n,mw[32010],mv[32010],fw[32010][3],fv[32010][3],f[32010],v,p,q;  
int main()  
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&v,&p,&q);
		if(q==0)
		{
			mw[i]=v;
			mv[i]=v*p;
		}  
		else
		{
			fw[q][0]++;
			fw[q][fw[q][0]]=v;
			fv[q][fw[q][0]]=v*p;
			}
	}
	for(int i=1;i<=m;++i)
		for(int j=n;j>=mw[i];--j)
		{
			f[j]=max(f[j],f[j-mw[i]]+mv[i]);//挑选附件几种情况 
			if(j>=mw[i]+fw[i][1])f[j]=max(f[j],f[j-mw[i]-fw[i][1]]+mv[i]+fv[i][1]);
			if(j>=mw[i]+fw[i][2])f[j]=max(f[j],f[j-mw[i]-fw[i][2]]+mv[i]+fv[i][2]);
			if(j>=mw[i]+fw[i][1]+fw[i][2])  
			f[j]=max(f[j],f[j-mw[i]-fw[i][1]-fw[i][2]]+mv[i]+fv[i][1]+fv[i][2]);  
		}
	printf("%d",f[n]);
	return 0;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值