• 题解【P1833 樱花】


    题目

    (n) 棵樱花,有三种:

    1. 只能看一次
    2. 最多看 (A_i)
    3. 能无限看

    看每棵樱花都需要一定时间 (T_i),求从 (T_s) 开始,到 (T_e) 结束(时间)最多能看多少樱花。

    题解

    混合背包板子,01 背包相当于 (1) 个物品的多重背包,完全背包相当于 inf 个物品的多重背包,都用多重背包即可。

    要二进制拆分优化,注意多重背包的 inf 不能开太大,不然会 RE .

    #include<iostream>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<iterator>
    #include<cctype>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    namespace Main
    {
    	const int N=1000005,INF=0x3f3f3f3f;
    	int t,T,n,c[N],v[N],dp[N];
    	struct node{int T,C,P;}a[N];
    	void split() // 二进制拆分 
    	{
    		for (int i=0;i<n;i++)
    		{
    			int z=1;
    			while (a[i].P) // index from 0 => index from 1
    			{
    				c[++T]=z*a[i].T; v[T]=z*a[i].C; a[i].P-=z; z<<=1;
    				if (a[i].P<z){c[++T]=a[i].T*a[i].P; v[T]=a[i].C*a[i].P; break;}
    			}
    		}
    	}
    	void zbag() // 01 背包 
    	{
    		for (int i=1;i<=T;i++)
    			for (int j=t;j>=c[i];j--)
    				dp[j]=max(dp[j],dp[j-c[i]]+v[i]);
    	}
    	inline void mbag(){split(); zbag();} // 多重背包 
    	int main()
    	{
    		int hh1,mm1,hh2,mm2,Ts,Te;
    		scanf("%d:%d %d:%d %d",&hh1,&mm1,&hh2,&mm2,&n);
    		Ts=hh1*60+mm1; Te=hh2*60+mm2; t=Te-Ts;
    		for (int i=0;i<n;i++)
    		{
    			scanf("%d%d%d",&a[i].T,&a[i].C,&a[i].P);
    			if (!a[i].P) a[i].P=INF;
    		} mbag(); printf("%d",dp[t]);
    		return 0;
    	}
    }
    int main(){return Main::main();}
    
    
  • 相关阅读:
    ios 应用程序之间的跳转(内置程序的实现)
    iOS手势UIGustureRecognizer
    动画学习之Animating Views with Blocks
    get 和post 方式请求数据
    通过路径添加图片
    contentSize、contentInset和contentOffset区别
    bzoj1055 [HAOI2008]玩具取名 区间DP
    bzoj1025 [SCOI2009]游戏 动态规划
    POJ2299 树状数组求逆序对
    洛谷1525 关押罪犯NOIP2010 并查集
  • 原文地址:https://www.cnblogs.com/CDOI-24374/p/13942655.html
Copyright © 2020-2023  润新知