[NOIP2009 普及组] 道路游戏

这个题有点过于生艹了,好不容易想出前缀和来,前缀和里还有大坑
题链

sum[a][b]=sum[a][b-1]+jb[(a+b-1)%n][b];

sum[a][b]表示一个机器人以 工厂a 为起点,从第一秒走到第 b 秒拾到的金币,
但是 sum[k][i]-sum[k][j]表示的却不是以k为起点,
sum[k][i]-sum[k][j]表示的是以k+j 为起点的 从第 j+1 秒到第 i 秒捡到的所有金币,
因为当第一秒的起点固定时,随着时间的推移,时间也变了,位置也变了
简直是自找麻烦

#include
#include
#include
#define ll long long
#define go(i,a,b) for(int i=a;i<=b;++i)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
int jb[1000+10][1000+10];
int sum[1000+20][1000+10];
int cost[1000+21];
int dp[1000+2];
int n,m,p;

void f(){
memset(dp,-999999,sizeof(dp));
dp[0]=0;
go(i,1,m){
    go(j,max(i-p,0),i-1){
        go(k,0,n-1){
            int dpi0=dp[j]+sum[(k-j+n*1000)%n][i]-sum[(k-j+n*1000)%n][j]-cost[k];
            dp[i]=max(dpi0,dp[i]);
            //printf("%d %d %d: %d\n",k,j+1,i,sum[(k-j+1+n*1000)%n][i]-sum[(k-j+1+n*1000)%n][j]);
        }

    }



}


cout<<dp[m];

}

int main(){
cin>>n>>m>>p;

go(i,0,n-1)
    go(j,1,m){scanf("%d",&jb[i][j]);}
go(i,0,n-1)scanf("%d",&cost[i]);
go(i,0,n-1){
    go(j,1,m){
        sum[i][j]=sum[i][j-1]+jb[(i+j-1)%n][j];
        //printf("%d %d: %d\n ",i,j,sum[i][j]);
    }
//printf("\n");
    }



//cout<<666;
f();


return 0;
}

再来看看别人的代码,过于生艹了,确实明白自己是有多自找麻烦了

# include
# include
using namespace std;
int n,m,p;
int pay[1001];
int money[1001][1001];
int f[1001];
int main()
{
    cin>>n>>m>>p;
    memset(f,-999999,sizeof(f));
    f[0]=0;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        cin>>money[i][j];
    for(int i=1;i<=n;i++)
      cin>>pay[i];
    for(int i=1;i<=m;i++)
      for(int j=1;j<=n;j++)
        {
            int ff=j-1;
            if(!ff) ff=n;
            int ss=money[ff][i];
            for(int k=1;k<=p;k++)
              {
                  if(i-k<0) break;
                  f[i]=max(f[i],f[i-k]+ss-pay[ff]);
                  ff--;
                  if(!ff) ff=n;
                  ss+=money[ff][i-k];
              }
        }
    cout<<f[m];
    return 0;
}

你可能感兴趣的:(线性dp,算法,动态规划)