51 nod 1522 上下序列——序列dp
生活随笔
收集整理的這篇文章主要介紹了
51 nod 1522 上下序列——序列dp
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522
很好的思想??紤]從小到大一對一對填數(shù),這樣也能對它的大小限制做一些操作了。
因?yàn)閺男〉酱?#xff0c;所以只能全填在左邊、全填在右邊、兩邊各填一個。記錄左邊填到了哪個位置,就可知右邊填到了哪個位置。轉(zhuǎn)移之前判斷一下這樣填是否合法即可。
新的不合法的狀態(tài)只會和現(xiàn)在填的兩個位置有關(guān)。
注意輸入格式!!符號前后有空格!!!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=40,M=105; int n,m,x[M],y[M],sgn[M],tx,ty; ll dp[N][N<<1],ans; char ch[20]; bool check(int p0,int p1,int r,int fx) {//printf("p0=%d p1=%d r=%d fx=%d\n",p0,p1,r,fx);for(int i=1;i<=m;i++)if(sgn[i]==0&&( ( (x[i]==p0||x[i]==p1)&&y[i]!=p0&&y[i]!=p1)||( (y[i]==p0||y[i]==p1)&&x[i]!=p0&&x[i]!=p1) ) )return 0;//以前都合法,不合法僅出現(xiàn)在p0、p1位置上if(!fx){for(int i=1;i<=m;i++){//printf("sgn[%d]=%d\n",i,sgn[i]);if(sgn[i]==1||sgn[i]==2){tx=x[i];ty=y[i];if(sgn[i]==2)swap(tx,ty);//printf("tx=%d ty=%d p0=%d p1=%d r=%d\n",tx,ty,p0,p1,r);if((ty==p0||ty==p1)&&tx>=p0&&tx<r) return 0;}if(sgn[i]==3||sgn[i]==4){tx=x[i];ty=y[i];if(sgn[i]==4)swap(tx,ty);if((ty==p0||ty==p1)&&tx>p1&&tx<r) return 0;}}}if(fx==1){for(int i=1;i<=m;i++){if(sgn[i]==1||sgn[i]==2){tx=x[i];ty=y[i];if(sgn[i]==2)swap(tx,ty);if((ty==p0||ty==p1)&&tx<=p1&&tx>r) return 0;}if(sgn[i]==3||sgn[i]==4){tx=x[i];ty=y[i];if(sgn[i]==4)swap(tx,ty);if((ty==p0||ty==p1)&&tx<p0&&tx>r) return 0;}}}if(fx==2){for(int i=1;i<=m;i++){if(sgn[i]==1||sgn[i]==2){tx=x[i];ty=y[i];if(sgn[i]==2)swap(tx,ty);if((ty==p0||ty==p1)&&tx>=p0&&tx<=p1) return 0;}if(sgn[i]==3||sgn[i]==4){tx=x[i];ty=y[i];if(sgn[i]==4)swap(tx,ty);if((ty==p0||ty==p1)&&tx>p0&&tx<p1) return 0;}}}return 1; } int main() {scanf("%d%d",&n,&m);ch[0]=getchar();while(ch[0]!='\n')ch[0]=getchar();for(int i=1,len=0,j;i<=m;i++,len=0){ch[++len]=getchar();while(ch[len]!='\n')ch[++len]=getchar();for(j=1;j<len;j++){if(ch[j]>='0'&&ch[j]<='9')x[i]=(x[i]<<3)+(x[i]<<1)+ch[j]-'0';else break;}while(ch[j]==' ')j++;//printf("j=%d chj=(%c)\n",j,ch[j]);if(ch[j]=='=') sgn[i]=0,j++;else if(ch[j]=='<'&&ch[j+1]=='=')sgn[i]=3,j+=2;else if(ch[j]=='>'&&ch[j+1]=='=')sgn[i]=4,j+=2;else if(ch[j]=='<')sgn[i]=1,j++;else if(ch[j]=='>')sgn[i]=2,j++;while(ch[j]==' ')j++;//printf("j=%d chj=(%c)\n",j,ch[j]);for(;j<len;j++)y[i]=(y[i]<<3)+(y[i]<<1)+ch[j]-'0';//printf("x=%d sgn=%d y=%d\n",x[i],sgn[i],y[i]); }dp[0][0]=1;for(int i=0,lm;i<n;i++){lm=(i<<1);for(int j=0,r;j<=lm;j++){//if(dp[i][j])printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]);r=(n<<1)-(lm-j)+1;if(check(j+1,j+2,r,0))dp[i+1][j+2]+=dp[i][j];//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j+2,dp[i+1][j+2],i,j);if(check(r-2,r-1,j,1))dp[i+1][j]+=dp[i][j];//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j,dp[i+1][j],i,j);if(check(j+1,r-1,0,2))dp[i+1][j+1]+=dp[i][j];//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j+1,dp[i+1][j+1],i,j); }}int lm=(n<<1);for(int j=0;j<=lm;j++) ans+=dp[n][j];printf("%lld\n",ans/3);return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/Narh/p/9672719.html
總結(jié)
以上是生活随笔為你收集整理的51 nod 1522 上下序列——序列dp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 心遇APP怎么注销账号
- 下一篇: 悠悠人生怎么登不了