• RowGame TopCoder


    传送门

    分析

    首先不难想到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;
            }
    };
  • 相关阅读:
    Nginx详解(正向代理、反向代理、负载均衡原理)
    java List的初始化
    nginx配置实现负载均衡
    SQL中where与having的区别
    数据库中where与having区别~~~
    group by的使用
    wm_concat函数
    Nginx配置upstream实现负载均衡1
    Nginx配置upstream实现负载均衡
    java
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9304527.html
Copyright © 2020-2023  润新知