1. 程式人生 > >題解 CF567F 【Mausoleum】

題解 CF567F 【Mausoleum】

從放第一本書開始推,每次放兩本相同高度的,設$f_{i,j}$為左邊放i本書,右邊放j本書的方案,放書的時候判斷一下是否合法,如果合法,$f_{i,j}$+=$f_{i-2,j}$,$f_{i-1,j-1}$,$f_{i,j-2}$  ,這個方程應該不難理解   

至於條件可以用鄰接表,注意一下鄰接表的資料範圍,因為書的位置有200個,正反都存一遍就好了
符號的正反:注意與 >= 相對的是 <= , 不是 <
這是我用了 N(N>20) 次除錯換來的······

得到的結果要除以3,因為當放最後兩本書時,$f_{i-2,j}$==$f_{i-1,j-1}$==$f_{i,j-2}$


上程式碼:

#include<bits/stdc++.h>
using namespace std;
long long n,f[210][210],tot,k,ans;
long long head[210],next11[410],ver[410],edge[410];
//一定開long long,一定開long long,一定開long long
void add(long long x,long long y,long long z){
    next11[++tot]=head[x],ver[tot]=y,edge[tot]=z,head[x]=tot;
}//鄰接表
bool spfa(long long l,long long r,long long ll,long long rr){ //尋找出邊,l表示放的兩本書中左邊的那本,r是右邊那本,ll表示沒有放書的區間的左端點,rr表示右端點,可知 ll~rr 中的書高度都大於將要放的兩本書 for(int i=head[l];i;i=next11[i]) { int y=ver[i],z=edge[i]; if(y==r){ if(z==2||z==4) return false; }//特判,等於的情況只可能:出邊為放的另一本書的位置
else if(z<=2) { if(y<ll||y>rr) return false; } else if(z>=4) { if(y>ll&&y<rr) return false; } else if(z==3) return false; }//尋找與左端點有關的條件 for(long long i=head[r];i;i=next11[i]) { long long y=ver[i],z=edge[i]; if(y==l){ if(z==2||z==4) return false; } else if(z<=2) { if(y<ll||y>rr) return false; } else if(z>=4) { if(y>ll&&y<rr) return false; } else if(z==3) return false; }//同上 return true; } int main(){ cin>>n>>k; for(int i=1;i<=k;i++) { long long x,y,z=0; string c; cin>>x>>c>>y; if(c[1]=='=') { if(c[0]=='<') z=1; else z=5; } else { if(c[0]=='=') z=3; if(c[0]=='<') z=2; if(c[0]=='>') z=4; } if(x==y) { if(z==2||z==4) { cout<<0; return 0; } else continue; } add(x,y,z); add(y,x,6-z);//懂我為什麼強調了吧 } f[0][0]=1; for(int i=1;i<=n;i++) { for(int j=0;j<=2*i;j++) { if(j>=2&&(k==0||spfa(j-1 , j , j+1 , 2*n-2*i+j))) f[j][2*i-j]+=f[j-2][2*i-j]; if(j>=1&&2*i-j>=1&&(k==0||spfa( j , 2*n-2*i+j+1 , j+1 , 2*n-2*i+j))) f[j][2*i-j]+=f[j-1][2*i-j-1]; if(2*i-j>=2&&(k==0||spfa(2*n-2*i+j+1 , 2*n-2*i+j+2 , j+1 , 2*n-2*i+j))) f[j][2*i-j]+=f[j][2*i-j-2]; }//自行理解,最好畫個圖 } for(int i=0;i<=2*n;i++) ans+=f[i][2*n-i];//ans累加, cout<<ans/3;//重要 return 0; }