uva 1099 狀態壓縮(dp專組E)

2021-07-11 13:28:35 字數 1361 閱讀 3525

題意:有x*y的矩陣塊,問能否把該矩陣切成n塊大小分別為a0,a1,a(n-1的小塊。每一刀切到底。

解題分析:

現在我們有任意a*b(a

a. 如果x = 1,那麼可以將矩陣塊切成x個小塊。

b .否則我們切一刀把矩陣塊分成兩個子塊即把x個小塊分成x0和x1塊。

我們利用狀態壓縮的方法,定義這x塊分別為s的二進位制為1處表示的矩陣塊(在輸入時,矩陣塊是有順序的)那麼s1 = s^s0.)(x為s的二進位制中1的個數)

(我們定義這x塊大小的總和為sum[s],則sum[s] =sum[s0]+sum[s1],同時

a*b的矩陣塊這一條件可以等價為,短邊為

a,矩陣塊大小為

sum[s]

,另一邊

b=sum[s]/a)

則可以將a*b的矩陣塊切成x塊條件是:

對於所有的s0,

s1:(即x為s的所有子集,s1為s0對s的補集)

1)  sum[s0]%a == 0(x塊可以通過切b邊分成x0和x1塊)&&(一邊為

a,總和為

sum[s0]

的矩陣塊可以切成

x0塊)&&(一邊為

a,總和為

sum[s1]

的矩陣塊可以切成

x1塊)

2)  或者sum[s0]%b== 0(x塊可以通過切a邊分成x0和x1塊)&&(一邊為

b,總和為

sum[s0]

的矩陣塊可以切成

x0塊)&&(一邊為

b總和為

sum[s1]

的矩陣塊可以切成

x1塊)

如果都不滿足,則不能滿足條件。

因為會多次詢問子問題(一邊為

a,總和為

sum[s0]

的矩陣塊可以切成

x0塊),通過記憶化搜尋的方法降低複雜度。

具體**如下:

#includeusing namespace std;

const int maxn = 17;

int a[maxn];

int sum[1<>1)+(x&1);

}int count_bit(int x)

return cnt;

}int dfs(int s,int x)

return dp[s][x] = 0;

}int main(){

int n;

int ca = 1;

while(cin>>n&&n){

int x,y;

cin>>x>>y;

memset(sum,0,sizeof(sum));

for(int i =0;i>a[i];

for(int s = 1;s<(1<

UVa 10944 狀態壓縮DP

第一道狀態壓縮dp題,感覺要好好學習這種思維方式 首先設l的位置為 pointx 0 pointy 0 其他節點的位置為 pointx i pointy i 然後求出各個節點之間的距離dis i j max 我們用乙個n位2進製數 bn 1,b0 表示堅果收集情況的組合狀態 其中bi 0表示第i 1...

UVA 6625 狀態壓縮dp

這個題目的意思是給定k,n k,n 7 並給定k行每行有幾個連續的空格,所有的行左對齊,每一行最多7個,下面的行的空格數 上面相鄰行的空格數 給定乙個填數字的規則,當對於任意位置i,j num i j num i 1 j num i j num i j 1 問有 只用數字1 n 有多少種填滿空格的方...

uva11795 簡單狀態壓縮DP

一看到n 16就想到狀態壓縮dp了,而且只要儲存這個狀態就行了 轉移時也用狀態壓縮的轉移方法,比較兩個二進位制數,就能知道能否從已知狀態轉移到需要的狀態 開始沒看到題目給的就是二進位制數,自己還轉換成了二進位制 還有要記得用longlong 不能因為這個wa 還有位運算還不是很熟悉,可以用異或來去掉...