luogu P1833 樱花 看成混合背包

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int N=30000+10;
const int mod=1000007;
int a[N];
int read()
{
    int res=0,ch,flag=0;
    if((ch=getchar())=='-')             //判断正负
        flag=1;
    else if(ch>='0'&&ch<='9')           //得到完整的数
        res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
    return flag?-res:res;
}
int f[N];
int g[N];
int m,n;
int q[N];
signed main()
{
	int a,b,c,d;
	scanf("%d:%d %d:%d",&a,&b,&c,&d);
	m=(c-a)*60+d-b; 
	n=read();
	for(int i=1; i<=n; i++)
    {
        int v=read(),w=read(),s=read();
        if(s==0)
        {
            for(int j=v; j<=m; j++)
                f[j]=max(f[j],f[j-v]+w);
        }
        else
        {
            memcpy(g,f,sizeof f);
            for(int j=0; j<v; j++)
            {
                int hh=0,tt=-1;
                for(int k=j; k<=m; k+=v)
                {
                    if(hh<=tt&&q[hh]<k-s*v)
                        hh++;
                    if(hh<=tt)
                        f[k]=max(f[k],g[ q[hh] ]+(k-q[hh])/v*w);
                    while(hh<=tt&&g[ q[tt] ]-(q[tt]-j)/v*w<=g[k]-(k-j)/v*w)
                        tt--;
                    q[++tt]=k;
                }
            }
        }
    }
    cout<<f[m]<<endl;
    return 0;
}
posted @ 2020-03-23 18:38  晴屿  阅读(90)  评论(0编辑  收藏  举报