[bzoj1187][HNOI2007]神奇游乐园
來自FallDream的博客,未經允許,請勿轉載,謝謝,
經歷了一段艱辛的旅程后,主人公小P乘坐飛艇返回。在返回的途中,小P發現在漫無邊際的沙漠中,有一塊狹長的綠地特別顯眼。往下仔細一看,才發現這是一個游樂場,專為旅途中疲憊的人設計。娛樂場可以看成是一塊大小為n×m的區域,且這個n×m的區域被分成n×m個小格子,每個小格子中就有一個娛樂項目。然而,小P并不喜歡其中的所有娛樂項目,于是,他給每個項目一個滿意度。滿意度為正時表示小P喜歡這個項目,值越大表示越喜歡。為負時表示他不喜歡,這個負數的絕對值越大表示他越不喜歡。為0時表示他對這個項目沒有喜惡。小P決定將飛艇停在某個小格中,然后每步他可以移動到相鄰的上下左右四個格子的某個格子中。小P希望找一條路徑,從飛艇所在格出發,最后又回到這個格子。小P有一個習慣,從不喜歡浪費時間。因此,他希望經過每個格子都是有意義的:他到一個地方后,就一定要感受以下那里的驚險和刺激,不管自己是不是喜歡那里的娛樂項目。而且,除了飛艇所在格,其他的格子他不愿意經過兩次。小P希望自己至少要經過四個格子。在滿足這些條件的情況下,小P希望自己玩過的娛樂項目的滿意度之和最高。你能幫他找到這個最高的滿意度之和嗎?
n<=100 m<=6
?
很顯然是插頭dp
因為不要求全部走完,所以和回路有點區別。
如果兩個插頭是(),且其他都沒有插頭,可以直接更新答案。
如果兩個插頭都沒有,那么可以不選擇這一格進行轉移。
可以預處理狀態,最多127種,復雜度127nm
#include<iostream> #include<cstdio> #include<cstring> #define INF 1000000000 using namespace std; inline int read() {int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f; }int s[130],q[10],n,m,top=0,ans=-INF,tot=0,a[105][7],c[130][7],f[7][1<<14]; inline void R(int&x,int y){y>x?x=y:0;} int main() {n=read();m=read();for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)a[i][j]=read();for(int i=0;i<1<<(m<<1)+2;++i){s[++tot]=i;top=0;for(int j=0;j<=m;++j){int x=i>>(j<<1);if((x&3)==3) {top=-1;break;}if((x&3)==1) q[++top]=j;if((x&3)==2){if(!top) {top=-1;break;}c[tot][j]=q[top];c[tot][q[top]]=j;--top;}}if(top) --tot;}for(int i=0;i<7;++i)for(int j=0;j<1<<14;++j)f[i][j]=-INF;f[m][0]=0;for(int i=1;i<=n;++i){for(int j=1;j<=tot;++j){if(s[j]&3) f[0][s[j]]=-INF;else f[0][s[j]]=f[m][s[j]>>2];}for(int j=1;j<=m;++j){int x=(j-1)<<1;for(int k=1;k<=tot;++k) f[j][s[k]]=-INF;for(int k=1;k<=tot;++k){int p=(s[k]>>x)&3,q=(s[k]>>(x+2))&3;if(!p&&!q){R(f[j][s[k]],f[j-1][s[k]]);R(f[j][s[k]^(9<<x)],f[j-1][s[k]]+a[i][j]);}else if(p&&q){if(p==1&&q==1)R(f[j][s[k]^(5<<x)^(3<<(c[k][j]<<1))],f[j-1][s[k]]+a[i][j]);if(p==1&&q==2)if(s[k]==(9<<x)) R(ans,f[j-1][s[k]]+a[i][j]);if(p==2&&q==1)R(f[j][s[k]^(6<<x)],f[j-1][s[k]]+a[i][j]);if(p==2&&q==2)R(f[j][s[k]^(10<<x)^(3<<(c[k][j-1]<<1))],f[j-1][s[k]]+a[i][j]);}else{R(f[j][s[k]],f[j-1][s[k]]+a[i][j]);R(f[j][s[k]^(p<<x)^(q<<x+2)|(p<<x+2)|(q<<x)],f[j-1][s[k]]+a[i][j]);}}}}cout<<ans;return 0; }?
轉載于:https://www.cnblogs.com/FallDream/p/bzoj1187.html
總結
以上是生活随笔為你收集整理的[bzoj1187][HNOI2007]神奇游乐园的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SO_REUSEADDR SO_REU
- 下一篇: 软件质量包括哪些特性?软件质量保证的主要