感覺現在只會用比較無腦比較暴力的狀壓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 不得不考慮一些沒用的操作 所以就考慮乙個問題 這個題的石子數太少了,在一定的範圍內,你不管怎樣跳,石子數也不會增加,所以你就可以把多...