P1833 樱花(二进制优化背包)

题目背景

《爱与愁的故事第四弹·plant》第一章。

题目描述

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

输入格式

共 n+1n+1行:

第 11 行:现在时间 T_sTs(几时:几分),去上学的时间 T_eTe(几时:几分),爱与愁大神院子里有几棵樱花树 nn。这里的 T_sTsT_eTe 格式为:hh:mm,其中 0 leq hh leq 230hh23,0 leq mm leq 590mm59,且 hh,mm,nhh,mm,n 均为正整数。

第 22 行到第 n+1n+1 行,每行三个正整数:看完第 ii 棵树的耗费时间 T_iTi,第 ii 棵树的美学值 C_iCi,看第 ii 棵树的次数 P_iPiP_i=0Pi=0 表示无数次,P_iPi 是其他数字表示最多可看的次数 P_iPi)。

输出格式

只有一个整数,表示最大美学值。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
int n;
int dp[maxn];
int a[maxn];
int b[maxn];
int c[maxn];
int w[maxn];//表示 
int v[maxn];//表示拆分后背包的容量 
int main () {
    int h1,m1,h2,m2;
    scanf("%d:%d %d:%d",&h1,&m1,&h2,&m2);
    int V=h2*60+m2-h1*60-m1;
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
        if (!c[i]) c[i]=1e6;
    }
    int tot=0;
    for (int i=1;i<=n;i++) {
        int tt=1;
        while (c[i]) {
            w[++tot]=tt*a[i];
            v[tot]=tt*b[i];
            c[i]-=tt;
            tt<<=1;
            if (c[i]<tt) {
                w[++tot]=a[i]*c[i];
                v[tot]=b[i]*c[i];
                break;
            }
        }
    }
    for (int i=1;i<=tot;i++)
        for (int j=V;j>=w[i];j--)
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    printf("%d
",dp[V]);
} 
原文地址:https://www.cnblogs.com/zhanglichen/p/13462267.html