• 樱花 混合背包


    题目描述
    爱与愁大神后院里种了n棵樱花树,每棵都有美学值Ci。爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:一种樱花树看一遍过,一种樱花树最多看Ai遍,一种樱花树可以看无数遍。但是看每棵樱花树都有一定的时间Ti。爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学。

    输入格式
    共n+1行:

    第1行:三个数:现在时间Ts(几点:几分),去上学的时间Te(几点:几分),爱与愁大神院子里有几棵樱花树n。

    第2行~第n+1行:每行三个数:看完第i棵树的耗费时间Ti,第i棵树的美学值Ci,看第i棵树的次数Pi(Pi=0表示无数次,Pi是其他数字表示最多可看的次数Pi)。

    输出格式
    只有一个整数,表示最大美学值。

    输入输出样例
    输入 #1
    6:50 7:00 3
    2 1 0
    3 3 1
    4 5 4
    输出
    11

    很明显就是混合背包问题,01背包和完全背包可以直接套模板,多重背包可以二进制拆分转化为01背包,刚开始拆分又拆错了,每个多重背包有最大次数,拆分的物品不仅是小于他的二进制数还得满足这些数的和必须等于他的次数,因为物品的不能超过他的最大次数

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=100010;范围一定得开大点
    ll n,m,x,w[N],t[N],dp[N],idx;
    bool st[N];
    int main()
    {
    	int v,b,c,d,e;
    	scanf("%d:%d %d:%d %d",&b,&c,&d,&e,&n);
    	v=d*60+e-b*60-c;
    	for(int i=0;i<n;i++)
    	{
    		scanf("%d%d%d",&b,&c,&d);
    		if(!d) 
    		{
    			t[idx]=b;
    			w[idx]=c;
    			st[idx++]=1;//标记完全背包
    		}
    		else 
    		{
    			int cnt=1;
    			while(d>=cnt)//拆分,01背包的次数是1也不会拆错
    			{
    				t[idx]=1ll*b*(cnt);
    				w[idx++]=1ll*c*(cnt);
    				d-=cnt;
    				cnt= cnt<<1;
    			}
    			if(d!=0) 
    			{
    				t[idx]=1ll*b*(d);
    				w[idx++]=1ll*c*(d);
    			}
    		}
    	}
    	n=idx;
    	for(int i=0;i<n;i++)
    	{
    		if(st[i])
    			for(int j=t[i];j<=v;j++)
    				dp[j]=max(dp[j],dp[j-t[i]]+w[i]);
    		else 
    			for(int j=v;j>=t[i];j--)
    				dp[j]=max(dp[j],dp[j-t[i]]+w[i]);
    	}
    	cout<<dp[v];
    	return 0;
    }
    
  • 相关阅读:
    python3 入门
    Python2 的列表排序
    数据库阻塞SQL的隔离级别
    数据库阻塞讲解设计应用程序时避免阻塞的八个准则
    DELPHI学习简单类型
    DELPHI学习结构类型
    InsideVCL第3章面向对象程序语言和Framework
    数据库阻塞分析死锁并处理
    面向对象开发实践之路
    DELPHI hint 的应用
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871774.html
Copyright © 2020-2023  润新知