Uva 6430 - Points ...简单DP

               题意:

                       有N(N<=10^6)个target排成一列(标号为1~N)..现在要选择一些target..并且告诉对于每个target..其得分的方式..对于选了第i个target得分

                            1、若其左右没有一个target被选择...得ai分

                            2、若其左右中有一个target被选择.,.得bi分

                            3、若其左右中无一个target被选择...得ci分

                       问能得到的最大分数...

               题解:

                       由于影响一个位置的取值分数仅与其右边和做边的点有关..所以可以用dp[i][x][y]代表扫到了第i个..第i个target是否选择了..第i-1个target是否选择了的最大值..

 

Program:

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <string.h>
#define oo 1000000007
#define MAXN 1000500
using namespace std;
int dp[2][2][2],a[MAXN],b[MAXN],c[MAXN];
int turn(int l,int x,int r)
{
       if (!l && !r) return a[x];
       if (l+r==1) return b[x];
       return c[x];
}
int main()
{
       int N,t,i,j,x,k,ans; 
       while (~scanf("%d",&N))
       {
               a[0]=b[0]=c[0]=0;
               for (i=1;i<=N;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]);
               c[1]=c[N]=-oo;
               if (N==1) b[1]=-oo;
               memset(dp[0],-0x3f,sizeof(dp[0]));
               dp[0][0][0]=0;
               k=ans=0;
               for (t=1;t<=N+1;t++)
               {
                       k=1-k;
                       memset(dp[k],-0x3f,sizeof(dp[k]));
                       for (x=0;x<2;x++)
                         for (i=0;i<2;i++)
                           for (j=0;j<2;j++)
                           {
                                  if (i) //别忘了...
                                       dp[k][i][j]=max(dp[k][i][j],dp[1-k][x][i]+turn(x,t-1,j));
                                    else
                                       dp[k][i][j]=max(dp[k][i][j],dp[1-k][x][i]);
                                  ans=max(ans,dp[k][i][j]);
                           }
               }
               printf("%d\n",ans);

       }
       return 0;
}


你可能感兴趣的:(Uva 6430 - Points ...简单DP)