题意:
有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; }