Codeforces 358D【DP】
思路:
dp[i][0] 代表取的时候左边没有
dp[i][1] 代表取的时候右边没有
dp[i][2] 代表取的时候左右都没有
dp[i][3] 代表取的时候左右都有
然后自己转移吧= =、
dp[i][1] 代表取的时候右边没有
dp[i][2] 代表取的时候左右都没有
dp[i][3] 代表取的时候左右都有
注意两个区间端点:
如果旁边有取a[i], 如果没有取b[i]。
只有一个的时候取a[i]。。。。
太狗了,这题意!
#include<bits/stdc++.h> using namespace std; typedef __int64 LL; const int INF=0x3f3f3f3f; int dp[3005][4]; int a[3005]; int b[3005]; int c[3005]; void DP(int n) { if(n==1) { printf("%d\n",a[1]); return; } memset ( dp , -0x3f , sizeof ( dp ) ); dp[1][0]=a[1]; dp[1][2]=b[1]; dp[1][1]=-INF; dp[1][3]=-INF; for(int i=2;i<n;i++) { dp[i][0]=max(dp[i-1][0]+b[i],dp[i-1][3]+b[i]); dp[i][1]=max(dp[i-1][1]+b[i],dp[i-1][2]+b[i]); dp[i][2]=max(dp[i-1][0]+c[i],dp[i-1][3]+c[i]); dp[i][3]=max(dp[i-1][1]+a[i],dp[i-1][2]+a[i]); } dp[n][1]=max(dp[n-1][1]+a[n],dp[n-1][2]+a[n]); dp[n][2]=max(dp[n-1][0]+b[n],dp[n-1][3]+b[n]); printf("%d\n",max(dp[n][1],dp[n][2])); } void solve() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++) scanf("%d",&c[i]); DP(n); } int main() { solve(); return 0; } /* 4 1 2 3 4 4 3 2 1 0 1 1 0 */