1. 程式人生 > >[JOI 2015 Final]分蛋糕 2

[JOI 2015 Final]分蛋糕 2

link

試題分析

容易發現性質,選擇的是一段區間,但是貪心無法去維護這件事情,所以考慮$dp$,且我們只要去設計關於$JOI$的選擇。

設$dp(i,j)$為現在要在$[l,r]$區間內選擇,然後就可以隨便寫了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
inline int read(){
    int f=1
,ans=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();} return f*ans; } const int N=4001; int dp[N][N],n,val[N],maxn; int dfs(int l,int r){ if(l==r) return dp[l][r]=val[l]; if(l+1==r) return
dp[l][r]=max(val[l],val[r]); if(dp[l][r]!=-1) return dp[l][r]; int res=0; if(val[l+1]>val[r]) res=max(res,dfs(l+2,r)+val[l]); else res=max(res,dfs(l+1,r-1)+val[l]); if(val[l]<val[r-1]) res=max(res,dfs(l,r-2)+val[r]); else res=max(res,dfs(l+1,r-1)+val[r]); return
dp[l][r]=res; } signed main(){ memset(dp,-1,sizeof(dp)); n=read(); for(int i=1;i<=n;i++) val[i]=val[i+n]=read(); for(int i=1;i<=n+1;i++){ maxn=max(maxn,dfs(i,i+n-1)); } printf("%lld\n",maxn); }
View Code