狀態壓縮DP題目小節(二)

2021-09-08 21:56:00 字數 2449 閱讀 6339

最近做的狀態壓縮dp小節:

zoj 4257

一堆氣體相互碰撞產生能量,求最後能產生的最大能量,應該是很基礎的狀態壓縮dp吧,設dp[flag]表示狀態flag時能產生的最大能量,(flag中1表示該氣體還存在,0表示該氣體已經消失)邊界條件是flag所有位都為一時,這時產生的能量為0,然後就列舉最後剩下的氣體,求最大值即可。

#include #include #include #include using namespace std;

int dp[1<<10];

int bo[11][11];

int n;

int max(int a,int b)

int dfs(int flag)}}

}return dp[flag]=ans;

}int main()

memset(dp,-1,sizeof(dp));

int ans=0;

dp[(1<

hdu 3001:

類似於tsp問題,但是這裡不同的是每個點最多可以走兩次,而不是一次,所以我們可以用三進製來表示每乙個狀態,我們設dp[now][flag]表示目前在now點狀態為flag時的最小花費,則邊界條件為當(1<<(now-1))==flag時,這時表示起點在now點,還沒開始走,則此時的最小花費是0,還有乙個邊界條件為(1<<(now-1))*2==flag,這表示從now點走到now點,這是不可能的,所以把最小花費設為無窮大,剩下的就是狀態轉移了。

dp[now][flag]=dp[pre][flag']+map[pre][now],滿足以下幾個條件:

1:pre!=now且map[pre][now]不為-1(也就是存在邊)

2:flag的第pre位不為0

3:flag'的第now位比flag的第now位少1.

我們求最小值即可,我們要列舉所有每一位都不為0的狀態,取它們的最小值即為答案。

#include #include #include #include #define inf 2100000000

using namespace std;

int bo[11][11];

int dp[11][60000];

int bit[60000][11];

int pow[12];

void init()

}pow[1]=1;

for(i=2;i<=11;i++)

pow[i]=pow[i-1]*3;

}int check(int x)

return 1;

}int n,m;

int min(int a,int b)

int ma=pow[n+1]-1,mi=ma/2;

int ans=inf;

for(i=1;i<=n;i++)

}if(ans==inf)

ans=-1;

printf("%d\n",ans);

}return 0;

}

poj 3311

也是類似於tsp問題,不過這個時候每個點可以走無限次,所以我們要用依次floyd演算法求一下個點之間的最短路,這裡設dist[u][v]表示u和v之間的最短路,然後就和平常求tsp問題一樣了,我們還是設dp[now][flag]表示當前在now點狀態為flag的最小花費,邊界條件為flag==(1<<(now-1))時,此時表示從起點開始走第一次到達到達now,為其他店還沒開hi走,則dp[now][flag]=dist[0][now],其他情況基本和上體一樣。

注意題目要求最後一定要回到0點。

#include #include #include #include #define inf 2100000000

using namespace std;

int map[11][11];

int dp[11][1<<10];

int n;

int min(int a,int b)

ll max(ll a,ll b)

int n;

ll dfs(int now,int pre,int flag)

int i,tru=0;

ll ans=0;

for(i=1;i<=n;i++)}}

}if(!tru)

if(ans)}}

}}

return dp[now][pre][flag]=ans;

}int main()

{ //freopen("dd.txt","r",stdin);

int ncase;

scanf("%d",&ncase);

while(ncase--)

{int m,i,a,b,j;

init();

scanf("%d%d",&n,&m);

for(i=1;i<=n;i++)

scanf("%d",&v[i]);

for(i=0;i

狀態壓縮DP 題目小節 (一)

最近被狀態壓縮dp虐得不行,今天終於決定正視自己的弱項,好好把dp練習一下,把今天做的幾道狀態壓縮dp總結一下,一定要想辦法擺脫dp弱菜這個標籤!poj 3254 應該是最基礎的狀態壓縮dp了吧,設dp i flag 表示第i行狀態為flag時的排放總數,預處理一下dp 1 flag 對於dp i ...

狀態壓縮dp入門題目

題目大意是有m n的玉公尺地,但其中有些是不肥沃的,不能種植。用1來代表肥沃,0代表不肥沃。另外奶牛不喜歡挨著吃,也就是說要間隔著種植,求有幾種種植方式,並將計算結果對1e8取模。include include using namespace std int dp 12 1 12 dp i s 第i...

狀態壓縮DP(二)

以前沒做過這種型別的狀態壓縮dp,剛開始看著沒想明白,後來跟著 看著好多了。題目 poj1185 炮兵陣地 題意 乙個矩陣,有一些地方可以放大炮,有的地方不能放,大炮對上下左右的攻擊範圍都是兩格。兩個大炮不能互相攻擊到,問最多放多少大炮。思路 求出每一行的所有狀態數,即用二進位制表示的所有可行狀態 ...