码迷,mamicode.com
首页 > 其他好文 > 详细

RowGame TopCoder - 10664

时间:2018-07-13 15:07:19      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:活动   lib   top   href   for   get   数字   后缀   map   

传送门

分析

首先不难想到O(k)做法,即dpi表示进行了几次,但复杂度明显爆炸,所以思考更优做法。我们发现数字个数很小,仅为可怜的50,所以从这里找突破口。我们发现每次可以在一个固定区域内进行刷分活动,当分数可以安全渡过中间的负数时可以选择渡过负数到另一个刷分区刷分,也可以留在本来的区域继续刷分,得到这些之后我们便可以考虑如何求出刷分区了,我们不难想出以点i为结尾的刷分区肯定是i的最大后缀和,得到以上结论后我们就可以dp了,当然这个题也可以建图跑最短路,代码挺容易理解了,具体实现看代码吧。

代码

dp

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl;
#define li long long
li num[1100],vl[1100],pre[1100],a[1100];
class RowGame{
      public:
          li score(vector<int>board,int k){
            int i,j,n=board.size();
            pre[0]=board[0];
            for(i=1;i<n;i++)
              pre[i]=(li)board[i]+pre[i-1];
            for(i=0;i<n;i++)
              if(pre[i]>=0){
                num[i]=k-1;
                vl[i]=pre[i];
              }
            a[0]=board[0];
            for(i=1;i<n;i++){
                a[i]=board[i];
                if(a[i-1]>0)
                  a[i]+=a[i-1];
            }
            li ans=0;
            for(i=0;i<n;i++)
              if(num[i]&&a[i]>0){
                ans=max(ans,vl[i]+num[i]*a[i]);
                li v=a[i]*2;
                for(j=i+1;j<n;j++){
                    li x=num[i]-2,y=vl[i]+v+pre[j]-pre[i];
                    if(y<0){
                      li t=(-y-1)/v+1;
                  x-=t*2;
                  y+=t*v;
                }
                if(x>num[j]||(x==num[j]&&y>vl[j])){
                  num[j]=x;
                  vl[j]=y;
                }
              }
            }
          return ans;
        }
};

建图+最短路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl;
#define li long long
int n,n2;
li g[1100][1100],a[1100],step[1100],vl[1100];
const li inf=1e16+7;
class RowGame{
      public:
          li score(vector<int>board,int k){
            int i,j,n=board.size(),n2=n+n;
          for(i=0;i<n2;i++)
            for(j=0;j<n2;j++)
              g[i][j]=-inf;
          for(i=0;i<n;i++){
            li s=0;
            for(j=i;j<n;j++){
              s+=board[j];
              g[i][j+n]=g[j+n][i]=s;
            }
          }
          for(i=0;i<n2;i++){
              a[i]=0;
              for(j=0;j<n2;j++)
                a[i]=max(a[i],g[i][j]+g[j][i]);
          }
          for(i=0;i<n2;i++){
            step[i]=inf;
            vl[i]=-inf;
          }
          step[0]=vl[0]=0;
          for(int p=0;p<n2;p++){
              for(i=0;i<n2;i++)
                if(step[i]!=inf)
                  for(j=0;j<n2;j++)
                    if(g[i][j]!=-inf){
                        li s=step[i],v=vl[i];
                        if(v+g[i][j]<0){
                          if(a[i]<=0)continue;
                          li ss=(-(v+g[i][j])-1)/a[i]+1;
                          s+=ss*2;
                          v+=ss*a[i];
                      }
                      v+=g[i][j];
                      s++;
                      if(s<step[j]||(s==step[j]&&v>vl[j])){
                        step[j]=s;
                        vl[j]=v;
                      }
                    }
          }
          li res=0;
          for(i=0;i<n2;i++)
            if(step[i]<=k){
              res=max(res,vl[i]);
              res=max(res,vl[i]+(k-step[i])/2*a[i]);
              if(step[i]!=k)
                for(j=0;j<n2;j++)
                  if(g[i][j]!=-inf)
                    res=max(res,vl[i]+(k-step[i]-1)/2*a[i]+g[i][j]);
            }
          return res;
        }
};

RowGame TopCoder - 10664

标签:活动   lib   top   href   for   get   数字   后缀   map   

原文地址:https://www.cnblogs.com/yzxverygood/p/9304527.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!