狀壓dp幾道題

2021-06-23 01:36:34 字數 3820 閱讀 8514

感覺現在只會用比較無腦比較暴力的狀壓dp,完全沒思考,就是列舉所有的狀態,等集訓結束了搜點要努力想dp方程的題做做。

hdu3681 prison break

大體意思就是給了張地圖,走路要耗費能量,有能量池能補充能量,求要走完特定的幾個點初始能量的最小值

因為給的點很少所以可以用狀壓dp,走過的各自可以重複走所以圖本身的意義就不大了,就是首先要spfa求一下各點之間的距離

dp[s][i]=max(dp[s-(1《我用了二分找初始能量的最小值,dp的過程很暴力就過了,這部分做的幾道題都比較基礎,一般都能暴力過。

#include#include#include#include#include#includeusing namespace std;

#define inf 10000000

typedef struct p

point;

char map[16][16];

int n,cnt,dp[35000][16],cnt_y,m,dir[4][2]=,d[16][16],num[16][16];

bool judge (int x,int y)

}} }

return;

}int cnt_bit(int x)

x>>=1;

j++;

} if(ans==1) return tmp;

return 0;

}bool check(int x)

continue;

} int j=0;

while((1<=d[j+1][k+1])

}k++;

}if(check(i)&&dp[i][j]>=0)

}j++;

} }return 0;

}int binary_search(int l,int r)

int m=(l+r)/2;

if(deal(m)) return binary_search(l,m);

return binary_search(m+1,r);

}int main()

return 0;

}

hdu1789 doing homework

題意就是許多作業,給你完成各項作業需要的時間和交作業的時限,晚交一天減一分,求減的最小分數。

一看見這種題就想用貪心,同樣n給的比較小,又是狀壓dp的專題,於是就沒仔細考慮貪心的問題。。

dp[s][i]=max(0,dp[s-(1<

#include#include#include#include#include#includeusing namespace std;

#define inf 100000000

int n,parent[35000],dp[35000],t[16],e[16],tmp1[16],tmp2[16];

string subject[20];

void ini()

for(int i=0;i<=(1<>=1;

i++;

} return ans;

}void exchange(int sit,int a,int &cnt)

if(i!=cnt2&&i==cnt1) return 1;

return 0;

}void deal()

else if(dp[i]==a)

return 0;

}

hdu 4856 tunnels

題意:一張地圖,上面有許多通道,給你各個通道的起點和終點,問要走所有的通道,在通道之間走的距離的最小值是多少。

跟a題幾乎完全一樣,spfa求出各個通道的起點到其他各個通道終點的最短距離,然後用狀壓dp暴力解決。

#include#include#include#include#include#includeusing namespace std;

#define inf 100000000

char map[25][25];

int dir[4][2]=,n,m,dis[20][20],dp[35000][20];

typedef struct pointpoint;

typedef struct tunneltunnel;

tunnel t[20];

bool check(point a)

}} }

for(int i=0;i<=m-1;i++)

return;

}void initial()

if(ret==1) return tmp;

return 0;

}void deal()

} return;

}int bit_cnt(int x)

return cnt;

}bool check(int sit,int ground)

void pre(int sit,int bit)

if(!(sit&2)&&!(sit&1)) pre(sit<<1|1,bit+1);

pre(sit<<1,bit+1);

return;

}void dfs(int row,int sit1,int sit2)

for(int i=0;i<=amo-1;i++)

dp[row][sit1][sit2]=max(dp[row+1][i][sit1]+bit_cnt(s[sit1]),dp[row][sit1][sit2]);

} }return;

}void init()

int main()

} int ans=0;

for(int i=0;i<=amo-1;i++)

ans=max(ans,dp[0][i][amo-1]);

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

} return 0;

}

poj 2411 mondriaan's dream

鋪磚的題,1*2的磚,問鋪滿給定區域有多少種鋪法,這題也是學長當時講的例題,如果自己想的話真是無從下手。

把豎著放的磚的上半部分計為1,即1表示下面必須為半塊磚。

然後列舉每一行的每乙個狀態,暴力求解。

一開始就想在乙個遞迴裡面解決整個問題,後來發現我的做法是在一行的狀態的值求完之前就去求下面的狀態,導致有最後的值有加重了的現象,然後腦子一抽乾脆每次遞迴出乙個狀態都在這個狀態上+1,成了個赤裸裸的dfs,但是還沒等著tle,樣例就沒過,然後沒耐心了,其實也想到要先求完上一行的所有狀態,但是當時總想著遞迴解決,還想要遞迴套遞迴,實在不好處理,翻出以前的**恍然大悟。。這尼瑪就是兩層迴圈加乙個遞迴= =

#include#include#include#include#includeusing namespace std;

__int64 h,w,dp[12][2500];

void dfs(__int64 father,__int64 sit,__int64 bit,__int64 row)

if((father&(1<<(w-bit-1)))) dfs(father,sit<<1,bit+1,row);

else

return;

}int main()

{ while(scanf("%i64d%i64d",&h,&w)!=eof&&(h!=0||w!=0))

{ memset(dp,0,sizeof(dp));

dp[0][0]=1;

for(__int64 i=1;i<=h;i++)

for(__int64 j=0;j<=(1<

還剩乙個d題,總是懶得思考想暴力解出來,t了n次,還是得用腦想吧- -做出來再貼

狀壓DP入門題

學習狀壓之前必須要熟練掌握位運算 位運算名 符號效果 and 按位與如果兩個相應的二進位制位都為1,則該位的結果值為1,否則為0 l or 按位或兩個相應的二進位制位中只要有乙個為1,該位的結果值為1 xor 按位異或 單身狗操作 若參加運算的兩個二進位制位值相同則為0,否則為1 取反 一元運算子,...

狀壓DP入門題集錦

poj 3254corn fields 題意 一塊n m的田,1表示這個地方可以種植,0代表這個地方不能種植。植物種植還必須滿足兩株植物不能相鄰 橫豎都不行 問共有幾種種植方法,而且當什麼都不種時認為是一種方法。解題思路 種植用1表示,不種植用0表示。每一行的情況就可以用乙個二進位制數state來儲...

過河(狀壓dp典型題)

這道題最簡單的dp,動態轉移方程很好推,因為它是由i s t轉移來的,所以 動態轉移方程為dp i min dp i s t q i 然而這個題的資料太大了。10 9 不得不考慮一些沒用的操作 所以就考慮乙個問題 這個題的石子數太少了,在一定的範圍內,你不管怎樣跳,石子數也不會增加,所以你就可以把多...