樱花(dp背包)

该问题是一个时间管理和资源优化的算法题,通过动态规划求解在限定时间(t2-t1)内能获得的最大樱花树美学值。利用dp数组记录不同时间点的最大美学值,同时用flw数组存储每个樱花树剩余的观看次数,通过状态转移找到最优解。
摘要由CSDN通过智能技术生成

题目

现在的时间是t1,要上学的时间是t2,现在有n棵樱花树,每颗樱花树都有美学值且有一定的观看次数(1到100或无穷),观看一颗樱花树能获得这棵樱花树的美学值,且观看一颗樱花树需要消耗一定的时间,求上学前我们能得到的最大美学值。

思路

dp[i]表示过了i分钟能获得的最大美学值,对于状态转移,首先dp[i]至少等于dp[i-1],然后我们枚举每一种可以在i时间内观看完的樱花树,且该樱花树的观看次数没使用完,假设当前枚举到的樱花树为j,其观看时间为t,美学值为v,dp[i]=max(dp[i],dp[i-t]+v)。

因为要判断一颗樱花树的观看次数是否使用完,我们维护另一个数组flw[i][j],表示过了i分钟取得最大美学值时j樱花树还能观看多少次,其状态转移分两种情况:第一种,dp[i]仍然等于dp[i-1],此时的flw[i][j]和flw[i-1][j]是相同的,第二种,此时dp[i]=dp[i-t]+v,那么flw[i][j]等于flw[i-t][j],最后将flw[i][k]--,k是上面所说拥有美学值v的樱花树。

下面代码中flw[i][j].num就是发挥了第二段的作用。

代码

#include <bits/stdc++.h>
using namespace std;
typedef struct sakura{
    int t,v,num;
}sakura;
sakura flw[1005][10005];
int dp[1005];
int main(){
    int stime,etime,n,temp;
    scanf("%d:%d",&stime,&temp);
    stime=stime*60+temp;
    scanf("%d:%d",&etime,&temp);
    etime=etime*60+temp;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>flw[0][i].t>>flw[0][i].v>>flw[0][i].num;
        if(flw[0][i].num==0)flw[0][i].num=-1;
    }
    int TIME = etime-stime;
    for(int i=1;i<=TIME;i++){
        dp[i]=dp[i-1];
        int add = i-1;
        int add2 = n;
        for(int j=0;j<n;j++){
            if(flw[0][j].t>i)continue;
            if(dp[i-flw[0][j].t]+flw[0][j].v>dp[i]&&flw[i-flw[0][j].t][j].num!=0){
                if(flw[i-flw[0][j].t][j].num==0);
                else {
                    dp[i]=dp[i-flw[0][j].t]+flw[0][j].v;
                    add=i-flw[0][j].t;
                    add2=j;
                }
            }
        }
        for(int j=0;j<n;j++){
            flw[i][j]=flw[add][j];
        }
        flw[i][add2].num--;
    }
    cout<<dp[TIME];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值