序列取数
題目描述
給定一個(gè)長為n的整數(shù)序列(n<=1000),由A和B輪流取數(shù)(A先取)。每個(gè)人可從序列的左端或右端取若干個(gè)數(shù)(至少一個(gè)),但不能兩端都取。所有數(shù)都被取走后,兩人分別統(tǒng)計(jì)所取數(shù)的和作為各自的得分。假設(shè)A和B都足夠聰明,都使自己得分盡量高,求A的最終得分。
輸入輸出格式
輸入格式:
第一行,一個(gè)正整數(shù)T,表示有T組數(shù)據(jù)。(T<=100)
接著T行,每行第一個(gè)數(shù)為n,接著n個(gè)整數(shù)表示給定的序列.
輸出格式:
輸出T行,每行一個(gè)整數(shù),表示A的得分。
題解:
這題剛看的時(shí)候覺得還挺簡單啊,不就是一個(gè)DP么,被刷成了這種難度,是什么鬼,然后看到了n<=1000,嗯,有點(diǎn)難度了,n^3做法過不了。。。但是稍微加點(diǎn)剪枝什么的幾個(gè)億開了O2不還是隨便過,然后發(fā)現(xiàn)T<=100.。。。出題人有病么,與其把時(shí)限開到3s,還不如少幾組數(shù)據(jù)。。。。于是發(fā)現(xiàn)N^3明顯不可做,開始考慮如何優(yōu)化掉一個(gè)n??紤]原來的DP方程,就是f[i][j]=s[i]-s[j-1]-min(d[i-1][j],[i-2][j],d[i-3][j]....d[i][j-2],d[i][j-1],0)。
發(fā)現(xiàn)我們可以記錄下來當(dāng)前左端和右端取的最優(yōu)方法,即
L[i][j]=min(f[i][j],L[i+1][j]);
R[i][j]=min(f[i][j],R[i][j-1]);
然后使f[i][j]=s[i]-s[j-1]-min(0,L[i+1][j],R[i][j-1])就可以了。
因?yàn)檫@三個(gè)都可以通過O1互相遞推出來,于是就省去了一個(gè)N
然后發(fā)現(xiàn)數(shù)據(jù)明顯不對(duì)頭,明明5個(gè)億在開O(2)的情況下竟跑了1700+ms。。。這題數(shù)據(jù)有毒,,,。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstdlib> #include <cmath> #include <string> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <set> #include <map> #define re register #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define MAXN 1e5+1 using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(arr) memset(arr, 0, sizeof(arr)) const int inf = 0x3f3f3f3f; int T,n,maxx,ans,f[1001][1001],L[1001][1001],R[1001][1001],a[200001],s[2001]; inline int read() {int x=0,c=1;char ch=' ';while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();while(ch=='-') c*=-1,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();return x*c; } int main() {//freopen("date.in","r",stdin);T=read();while(T--){n=read();for(re int i=1;i<=n;i++){a[i]=read();s[i]=s[i-1]+a[i];f[i][i]=L[i][i]=R[i][i]=a[i];}for(re int l=1;l<=n;l++){for(re int i=1;i<=n-l;i++){int j=i+l,maxx=0;maxx=min(maxx,min(L[i+1][j],R[i][j-1]));f[i][j]=s[j]-s[i-1]-maxx;L[i][j]=min(f[i][j],L[i+1][j]);R[i][j]=min(f[i][j],R[i][j-1]);}}printf("%d\n",f[1][n]);}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/victorique/p/8830679.html
總結(jié)
- 上一篇: swing JTable 更新数据
- 下一篇: 七牛2018春季校园招聘后端开发工程师笔