zoukankan      html  css  js  c++  java
  • Poetize6: Acting Cute

    3042: Acting Cute

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 59  Solved: 36
    [Submit][Status]

    Description

    正在rainbow的城堡游玩的freda恰好看见了在地毯上跳舞卖萌的水叮当……于是……
    freda:“呜咕>_< 我也要卖萌T_T!”
    rainbow给了freda N秒的自由活动时间,不过由于刚刚游览城堡有些累了,freda只想花B秒的时间来卖萌,剩下的时间她要在rainbow的城堡里睡个好觉好好休息一下。
    rainbow给这N秒每秒定义了一个值Ui,如果第i秒钟freda在卖萌,那么她可以获得Ui点卖萌指数lala~
    freda开始卖萌后可以随时停止,休息一会儿之后再开始。不过每次freda开始卖萌时,都需要1秒来准备= =,这一秒是不能获得卖萌指数的。当然,freda卖萌和准备的总时间不能超过B。
    更特殊的是,这N秒钟时间是环形的。也就是freda可以从任意时间开始她的自由活动并持续N秒。
    为了使自己表现得比水叮当更萌,现在freda想知道,她最多能获得多少卖萌指数呢?

    Input

    第一行包含两个整数N和B。
    第2~N+1行每行一个整数,其中第i+1行的整数表示Ui。

    Output

    输出一个整数,表示freda可以获得的最大卖萌指数。

    Sample Input

    5 3
    2
    0
    3
    1
    4

    Sample Output

    6

    对于100%的数据,0<=B<=N<=3600,0<=Ui<=200000。

    样例解释:
    freda选择从第2秒开始她的自由活动,持续N秒(2、3、4、5、1)。第4秒开始准备,第5、1秒卖萌(时间是环形的),获得2+4=6点卖萌指数。

    HINT

     

    Source

    题解:
    我连n^3的DP都没想出,给跪了!
    看了题解很好想。。。
    f[i][j][k]表示走到i,卖萌了j次,当前状态是k,k=0表没有卖萌,k=1表处于卖萌状态。
    然后
    f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1])
    f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+a[i])
    然后如果是环形的话
    我们可以证明如果最优解不是从1出发的,那么n和1的肯定都在卖萌!
    否则 我们就可以从1开始DP从而得出这个最优值!
    应该很好理解的。
    然后我们强制把n和1都设定为处在卖萌状态了,然后再做一次DP
    出题人的题解:http://hi.baidu.com/lydrainbowcat/item/0691bf7f2c46503c70442338
    不滚动也能A,我作死写了滚动结果t放在循环里了。。。查了0.5h。。。sad
    具体实现如下:
    代码:
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 5000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,t,ans,a[maxn],f[2][maxn][2];
    32 void dp()
    33 {
    34     t=0;
    35     for2(i,2,n)
    36     {
    37      t=1-t;
    38      for0(j,m)
    39       {
    40           f[t][j][0]=max(f[1-t][j][0],f[1-t][j][1]);
    41           if(j)f[t][j][1]=max(f[1-t][j-1][0],f[1-t][j-1][1]+a[i]);
    42       } 
    43     }
    44 }
    45 int main()
    46 {
    47     freopen("input.txt","r",stdin);
    48     freopen("output.txt","w",stdout);
    49     n=read();m=read();
    50     for1(i,n)a[i]=read();
    51     if(m<=1)printf("0
    ");
    52     for0(i,1)for0(j,m)for0(k,1)f[i][j][k]=-inf;
    53     f[0][0][0]=f[0][1][1]=0;
    54     dp();ans=max(f[t][m][0],f[t][m][1]);
    55     for0(i,1)for0(j,m)for0(k,1)f[i][j][k]=-inf;
    56     f[0][1][0]=f[0][1][1]=a[1];
    57     dp();ans=max(ans,f[t][m][1]);
    58     printf("%d
    ",ans);
    59     return 0;
    60 }
    View Code
     
  • 相关阅读:
    POJ 1789:Truck History
    POJ 1258:Agri-Net Prim最小生成树模板题
    POJ 1837:Balance 天平DP。。。
    杭电1754--I Hate It(线段树)
    Poj3259--Wormholes(Spfa 判负环)
    杭电1068--Girls and Boys(二分图最大独立集)
    杭电1010--Tempter of the Bone(Dfs+剪枝)
    杭电2647--Reward(反向拓扑)
    杭电1083--Courses(二分图匹配)
    杭电2063--过山车(二分匹配)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4049603.html
Copyright © 2011-2022 走看看