【洛谷P1717】钓鱼

题目大意:给定 N 个位置,每个位置有一个答案贡献值,在一个位置加了一次该位置的答案贡献值之后,该值会减掉一部分,从一个位置移动到另一个位置需要花费一定的时间,问:给定 M 单位的时间,如何移动使得答案贡献值最大。(初始在1位置)

题解:
引理:若想使答案贡献值最大,一定不能走回头路,因为走回头路时,可以在之前那个位置时就加一次答案贡献值,这样不会使结果更糟,证毕。
再考虑一个更简单的问题,即:没有移动的时间花费,那么就可以直接贪心,每次选序列中最大的数即可。因此,根据引理,可以枚举最远能够到达的位置,在开始时直接减掉从起点到该位置所有的跑路时间,把问题转化为没有移动的时间花费,直接贪心出答案,并更新最优解即可。

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
const int maxn=30;

int n,h,ans,f[maxn],d[maxn],t[maxn];

void read_and_parse(){
    scanf("%d%d",&n,&h),h*=12;
    for(int i=1;i<=n;i++)scanf("%d",&f[i]);
    for(int i=1;i<=n;i++)scanf("%d",&d[i]);
    for(int i=1;i<n;i++)scanf("%d",&t[i]);
}

void solve(){
    priority_queue<P> q;
    for(int i=1;i<=n;i++){
        int tot=0,s=h;
        while(q.size())q.pop();
        for(int j=1;j<i;j++)s-=t[j];
        for(int j=1;j<=i;j++)q.push(make_pair(f[j],j));
        for(int j=1;j<=s;j++){
            P now=q.top();q.pop();
            if(now.first<=0)break;
            tot+=now.first,now.first-=d[now.second];
            q.push(now);
        }
        ans=max(ans,tot);
    }
    printf("%d\n",ans);
}

int main(){
    read_and_parse();
    solve();
    return 0;
}

转载于:https://www.cnblogs.com/wzj-xhjbk/p/10012516.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值