标签:pst bsp strong out asc ase org jpg amp
题目:
Input
Output
Sample Input
1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0
Sample Output
1 0 1 2 3 5 144 51205
题意很简单就是求用1*2的小木块,有几种方法能构成h*w的长方体。
相当蛋疼的题目,可能是我比较菜吧,想了好久才找到适合DP的状态,而且状态数太多了,把内存的给爆了,迫不得以,用预处理去掉一维,内存才够用
状态的表示:
b是当前dp的矩形的宽度
dp[h][state]
h代表当前高度
state是三进制数来表示当前高度上每列的状态
2代表与当前高度同高
1代表比当前高度矮一格
0代表比当前高度矮两格
比如当
b=4
h=2
三进制2222,2221
分别代表2*4的矩形,和缺了一个角的2*4矩形
状态的转移:
为了防止出现重复的计算的情况,我们要保证状态转移的唯一性。
我想到方法是,每次操作剩下图形最高的列中最右边的列,因为这个列是唯一的,所以可以保证的转移的唯一性。
我们对这个列操作有两种
1,去掉这个两格,即去掉高2宽1的小木块
2,若这个列左边相邻的列也是与其等高的列,去掉这两个列个一格,即去掉高1宽2的小木块
代码实现:
因为这个转移方程挺复杂的,写成递推比较麻烦,所以我写成了记忆话搜索
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 long long dp[12][90000],ans[20][20]; 6 int u[20],k[20],b; 7 int check(int state) 8 { 9 int x=state,que[20]= {0},i; 10 for(i=0; i<=10; i++) 11 { 12 que[i]=x%3; 13 x/=3; 14 } 15 for(i=0; i<=10; i++) 16 { 17 if(que[i]==2) 18 { 19 if(que[i+1]==2) 20 que[i+1]=1; 21 else 22 return 0; 23 } 24 } 25 return 1; 26 } 27 long long dfs(int h,int state) 28 { 29 if(dp[h][state]==-1) 30 { 31 if(h==1) 32 { 33 dp[h][state]=check(state);/**当只剩下一列时,检查这列是否能用高1宽2的小木块组成*/ 34 } 35 else 36 { 37 int x,i; 38 x=state; 39 for(i=1; i<=b; i++)/**寻找最右边且高度与h相等的那列*/ 40 { 41 if(x%3==2) 42 { 43 break; 44 } 45 x/=3; 46 } 47 if(i>b) 48 dp[h][state]=dfs(h-1,state+u[b]);/**没有与h等高的列,所以h下降,扫描下一高度*/ 49 else 50 { 51 dp[h][state]=dfs(h,state-2*k[i]);/**去掉高2宽1的小木块*/ 52 if(i<b&&(x/3)%3==2)/**判断与x相邻列的是否也是与等高*/ 53 { 54 dp[h][state]+=dfs(h,state-k[i]-k[i+1]);/**去掉高1宽2的小木块*/ 55 } 56 } 57 } 58 } 59 return dp[h][state]; 60 } 61 int main() 62 { 63 int i,j,len; 64 u[1]=1; 65 k[1]=1; 66 for(i=2; i<=11; i++) 67 { 68 k[i]=k[i-1]*3; 69 u[i]=u[i-1]*3+1; 70 } 71 for(i=1; i<=11; i++)/**i是宽度*/ 72 { 73 len=q[i].size(); 74 b=i; 75 memset(dp,-1,sizeof(dp)); 76 if(i%2==1)/**判断奇偶,因为若面积是奇数则坑定种类为零,不用算了*/ 77 { 78 for(j=2; j<=i; j+=2)/**只算偶高度*/ 79 { 80 ans[i][j]=dfs(j,2*u[i]); 81 } 82 } 83 else 84 { 85 for(j=1; j<=i; j++)/**j是高度*/ 86 { 87 ans[i][j]=dfs(j,2*u[i]); 88 } 89 } 90 } 91 while(scanf("%d%d",&i,&j)&&i) 92 { 93 if(i<j) 94 swap(i,j); 95 printf("%I64d\n",ans[i][j]); 96 } 97 return 0; 98 }
标签:pst bsp strong out asc ase org jpg amp
原文地址:http://www.cnblogs.com/qswg/p/6298753.html