Codeforces Round #416 (Div. 2) C Vladik and Memorable Trip
阿新 • • 發佈:2019-01-14
根據題目要求,目的地相同的人必須在一個車廂中,或者坐下趟車。因此,每個對人有兩種決策:(1)上車(2)不上車
上車就必須保證,所有該目的的人之間的乘客也必須上車,這樣中間的人同理,這個區間會不斷擴張,直到不會有區間外的人跟這個區間裡的某人目的地相同為止。剩下的區間又會變成子問題,記憶化求解即可。
解題程式碼如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<map> #include<string> #include<queue> #include<vector> #include<list> #include<bitset> //#pragma comment(linker,"/STACK:1024000000,1024000000") using namespace std; typedef long long ll; #define INF 0x3f3f3f3f int n; int a[5005]; int dp[5005],fir[5005],lst[5005]; void read() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; } void init() { memset(fir,-1,sizeof fir); memset(lst,-1,sizeof lst); memset(dp,-1,sizeof dp); for(int i=1;i<=n;i++) { if(fir[a[i]]==-1) fir[a[i]]=i; lst[a[i]]=i; } } int get(int p) { if(p==0) return 0; if(dp[p]!=-1) return dp[p]; int res=0,l=fir[a[p]],i; for(i=p;i>=l;i--) { if(lst[a[i]]>p) break; l=min(l,fir[a[i]]); if(fir[a[i]]==i) res^=a[i]; } dp[p]=get(p-1); if(i<l) dp[p]=max(res+get(i),dp[p]); return dp[p]; } void solve() { printf("%d\n",get(n)); } int main() { read(); init(); solve(); return 0; }