POJ1038 Bugs Integrated, Inc 狀壓DP+優化
阿新 • • 發佈:2018-04-20
滿足 style urn 狀態轉化 algorithm ext light 鏈式前向星 屬於 Dfs優化(這個大概70-100%,有的人就能,反正我沒有),之後同樣,用鏈式前向星優化一下,就可以過了,當然,如果你還不滿足於這個時間復雜度的話,還可以繼續優化,這個就不寫在這裏了。
(1) 最簡單的4^10*N的枚舉(理論上20%)
(2) 優化優化200^3*N的枚舉(理論上至少50%)
(3) Dfs優化狀壓dp O(我不知道,反正過不了,需要再優化)(理論上80%)
(4) 再剩下的,卡常數+卡常數+一個小優化(自己想吧,有可能被卡一個點)
(5) 如果還沒有過,dfs中可能有重復的狀態,用鏈式前向星優化一下,就差不多了
(6) 以上屬於亂搞,正解在下面
(7) O(3^10*N),我們知道,設,我們更新第i行的狀態,那麽如果第i-1行的第j個位置不能被選取,則第i-2行的第j個位置同樣不可以被選取,那麽4^N狀態轉化為3^N,理論時間復雜度可能會超時(這個大概是60-70%的樣子),所以需要用到
亂搞程序
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> #include <cstdlib> #include <queue> using namespace std; #define N 155 #define M 205 #define max(a,b) ((a)<(b)?(b):(a)) int f[3][M][M],cur[N],n,m,K,can[M],p[1<<15],cnt2,head[M][M]; int to[M*M*30],to2[M*M*30],to3[M*M*30],cnt[M*M*30],next[M*M*30]; int a,b,ans,cnt4; void dfs(int f1,int f2,int step,int f3,int cnt1) { if(to[cnt4]!=f1||to3[cnt4]!=f2) { to[++cnt4]=f1; to2[cnt4]=f3; to3[cnt4]=f2; cnt[cnt4]=cnt1; next[cnt4]=head[a][b]; head[a][b]=cnt4; } if(step>=m)return ; if(step<m-1&&!(f1&(3<<step))&&!(f2&(3<<step))) { dfs(f1|(3<<step),f2|(3<<step),step+2,f3|(3<<step),cnt1+1); } if(step<m-2&&!(f1&(7<<(step)))) { dfs(f1|(7<<step),f2,step+3,f3|(7<<step),cnt1+1); } if(step<m-2&&!(f1&(7<<step))&&!(f2&(7<<step))) { dfs(f1|(7<<step),f2|(7<<step),step+3,f3,cnt1+1); } dfs(f1,f2,step+1,f3,cnt1); return ; } void init() { memset(cur,0,sizeof(cur)); memset(head,0,sizeof(head)); cnt4=0; } int main() { int T; scanf("%d",&T); while(T--) { init(); scanf("%d%d%d",&n,&m,&K); int mask=(1<<m)-1; for(int i=1;i<=K;i++) { int x,y; scanf("%d%d",&x,&y); cur[x]|=(1<<(y-1)); } cur[0]=cur[n+1]=mask; ans=0;cnt2=0; for(int j=0;j<=mask;j++) { int s=j; if(((s&3)==1)||(s!=0&&((((~s))&((~s)<<2))&&(((((~s))&((((~s)))<<2))>>1)&s))))continue; can[++cnt2]=j; p[j]=cnt2; } for(int i=1;i<=cnt2;i++) { for(int j=1;j<=cnt2;j++) { if((can[i]&can[j])!=can[i])continue; a=i,b=j; dfs(can[i],can[j],0,0,0); } } memset(f[1],0,sizeof(f[1])); for(int i=1;i<n;i++) { memset(f[(i+1)&1],0,sizeof(f[(i+1)&1])); for(int j=1;j<=cnt2;j++) { if(can[j]&cur[i])continue; for(int k=j;k<=cnt2;k++) { if((can[k]&cur[i-1]))continue; if((can[k]&can[j])!=can[j])continue; for(int l=head[j][k];l;l=next[l]) { if((to[l]&cur[i])||(to3[l]&cur[i-1])||(to2[l]&cur[i+1]))continue; f[(i^1)&1][p[to2[l]]][p[to[l]|to2[l]]]=max(f[(i^1)&1][p[to2[l]]][p[to[l]|to2[l]]],f[i&1][j][k]+cnt[l]); } if(i==1)break; } } for(int j=1;j<=cnt2;j++) { for(int k=1;k<=cnt2;k++) { ans=max(ans,f[(i+1)&1][j][k]); } } } printf("%d\n",ans); } return 0; }
POJ1038 Bugs Integrated, Inc 狀壓DP+優化