[NOIP2009]普及组T4 道路游戏

来源:互联网 发布:张艺兴发布会知乎 编辑:程序博客网 时间:2024/05/17 00:06

题意:在环形公路上,给定n个工厂制造机器人的花费以及n条道路每个时刻的金币数,一个时刻必须有也只能有一个机器人在公路上收集金币,求m时刻后能收集的最多金币。这题题意很明确,显然是dp,这里我们讲的是贪心的做法,另外还有单调队列的做法。

我们要尽可能多地收集金币,就得考虑第i时刻买不买机器人。所以我们要分清什么情况下买机器人,什么情况下不买机器人。
先介绍一下代码中要用到的数组及变量。

dp[i][j] 表示i时刻在j工厂能收集到的最多金币
step[i][j] 表示在i时刻在j工厂的机器人已经走的步数
pre[i] 表示i工厂前一个工厂编号,当i>1时,pre[i]=i-1;当i=1时,pre[i]=n
mx 表示当前时刻能得到的最多金币
pastmx 表示前一个时刻能得到的最多金币

买机器人的情况:
    (1)step[i-1][pre[j]]=p,即表示上个机器人已经走了p步,机器人不能再走了;(2)pastmx-cost[pre[j]]≥dp[i-1][pre[j]],即表示在i-1时刻的某个工厂收集到金币减去j工厂前一个工厂制造的花费仍大于等于i-1时刻到达j工厂前一个工厂收集到的金币数,也就是说pastmx-dp[i-1][pre[j]]足以支付pre[j]的制造费用,此时买机器人能走的步数比之前多,显然更优。

不买机器人的情况:
    不买机器人就是除去买机器人的情况,step加1,能获得的金币增加

#include<stdio.h>#include<algorithm>#include<iostream>#define oo 2000000000#define M 1005using namespace std;template <class T>inline void Rd(T &res){    char c;res=0;int k=1;    while(c=getchar(),c<48&&c!='-');    if(c=='-'){k=-1;c='0';}    do{        res=(res<<3)+(res<<1)+(c^48);    }while(c=getchar(),c>=48);    res*=k;}int n,m,p;int val[M][M];//i时刻第j段公路出现的金币数int cost[M];//第i个工厂的制造费用int dp[M][M];//i时刻在j工厂的最多金币 int step[M][M];//i时刻在j工厂的机器人走的步数 int pre[M];//i工厂前一个工厂的编号int pastmx,mx;int main(){    Rd(n);Rd(m);Rd(p);    for(int j=1;j<=n;j++)    for(int i=1;i<=m;i++)    Rd(val[i][j]);    for(int i=1;i<=n;i++){        Rd(cost[i]);        pre[i]=i-1;    }    pre[1]=n;    mx=-1<<30;    for(int i=1;i<=n;i++){        step[1][i]=1;        dp[1][i]=val[1][pre[i]]-cost[pre[i]];        mx=max(mx,dp[1][i]);    }    pastmx=mx;    for(int i=2;i<=m;i++){        mx=-1<<30;        for(int j=1;j<=n;j++){            if(step[i-1][pre[j]]<p&&pastmx-cost[pre[j]]<dp[i-1][pre[j]]){                step[i][j]=step[i-1][pre[j]]+1;                dp[i][j]=dp[i-1][pre[j]]+val[i][pre[j]];            }else{                step[i][j]=1;                dp[i][j]=pastmx-cost[pre[j]]+val[i][pre[j]];            }            mx=max(mx,dp[i][j]);        }        pastmx=mx;    }    printf("%d\n",mx);    return 0;}

刚看到这题的时候,直接敲了O(nmp)的DP,没往贪心的方面想,所以没做出来,现在想想还是很清晰的。

1 0
原创粉丝点击