Hdu 4804 Campus Design(给定一个图,0是不能放的,然后现在有1X1和1X2方块,要求铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法)
2016-08-08 11:18
363 查看
传送门:Hdu 4804 Campus Design
题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,要求铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法
思路:我们可以将那些’0’的位置默认成已经放了1×1,那么就是在原来的基础上增加一维数组,表示已经放了的的1x1的方格的数目
题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,要求铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法
思路:我们可以将那些’0’的位置默认成已经放了1×1,那么就是在原来的基础上增加一维数组,表示已经放了的的1x1的方格的数目
#include<bits/stdc++.h> using namespace std; const int maxn=1<<10; const int MOD=1e9+7; int dp[2][maxn][22],cur,n,m; char s[111][20]; void add(int &x,int y){ x+=y; if(x>=MOD) x-=MOD; } void update(int a,int b,int x,int y){ if(b&(1<<m)) add(dp[cur][b^(1<<m)][y],dp[cur^1][a][x]); } int main(){ int C,D; while(scanf("%d%d%d%d",&n,&m,&C,&D)!=EOF){ int all=(1<<m)-1; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) scanf("%s",s[i]); dp[0][all][0]=1,cur=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++){ cur^=1; memset(dp[cur],0,sizeof(dp[cur])); for(int sta=0;sta<=all;sta++) for(int k=0;k<=D;k++){ if(dp[cur^1][sta][k]==0) continue; if(s[i][j]=='0') update(sta,(sta<<1)^1,k,k); else{ update(sta,(sta<<1)^1,k,k+1); //放一块小的 update(sta,sta<<1,k,k); //不放1*2 if(i && !(sta & ( 1<<(m-1) ) ) )//竖着放1*2 update(sta,(sta<<1)^(1<<m)^1,k,k); if(j && !(sta & 1) ) //横着放1*2 update(sta,(sta<<1)^3,k,k); } } } int ans=0; for(int i=C;i<=D;i++) add(ans,dp[cur][all][i]); printf("%d\n",ans); } return 0; }
相关文章推荐
- 字符串处理算法(四)现在一个给定字符串中寻找子串的功能(不能使用库函数)[2014百度笔试题]
- 【数据结构】对一个数组按给定的下标排序,仅使用两两交换的方式,要求不能对数组进行扩容尽可能使用额外少的空间
- hdu 3183 A Magic Lamp(给一个n位的数,从中删去m个数字,使得剩下的数字组成的数最小(顺序不能变),然后输出)
- 对一个数组按给定的下标排序,仅使用两两交换的方式,要求不能对数组进行扩容尽可能使用额外少的空间。原数组为:A,B,C,D,E, 现给定新的位置为3, 0, 1, 4, 2那么排序为D,A,B,E,C
- hdu 3183 A Magic Lamp(给一个n位的数,从中删去m个数字,使得剩下的数字组成的数最小(顺序不能变),然后输出)
- 字符串处理算法(四)现在一个给定字符串中寻找子串的功能(不能使用库函数)[2014百度笔试题]
- 有一个int型数组,每两个相邻的数之间的差值不是1就是-1.现在给定一个数,要求查找这个数在数组中的位置
- 在一个长度为10的整形数组中,前9个元素是{12,23,34,45,56,67,78,89,90}。 现在要求输入一个整数,把它放到数组中正确的位置当中。(不能删除已有元素)
- 练习2-4:编一个程序统计文件中特定单词出现的次数(要求使用string类的运算符==来查找单词) .
- 删除一个单项链表的最中间的元素,要求时间尽可能短(不能使用两次循环)
- ACM457现在给出了一个只包含大小写字母的字符串,不含空格和换行,要求把其中的大写换成小写,小写换成大写,然后输出互换后的字符串。输入 第一行只有一个整数m(m<=10),表示测试数据组数。
- 删除一个单项链表的最中间的元素,要求时间尽可能短(不能使用两次循环)
- 编写函数求两个整数 a 和 b 之间的较大值。要求不能使用if, while, switch, for, ?: 以及任何的比较语句
- C++递归问题之二——n皇后问题:以四、八皇后为例,给定n个皇后要求将它们放在一个n维矩阵中,任意两个皇后不能出现在同一行、列、主副对角线上,输出具体的摆放方式
- c#:猜数字游戏!系统随机给出一个0至99(包括0和99)之间的数字,然后让你猜是什么数字。你可以随便猜一个数字,游戏会提示太大还是太小,从而缩小结果范围。经过几次猜测与提示后,最终推出答案
- 编写一个函数reverse_string(char * string)(递归实现)实现:将参数字符串中的字符反向排列。要求:不能使用C函数库中的字符串操作函数。
- 给定一个数组,该数组存贮R,G,B三种字符,将该数组按RGB顺序排序,不能使用辅助内存空间,且只能遍历数组一次。
- 17、有一个由大小写组成的字符串,现在需要对他进行修改, 将其中的所有小写字母排在答谢字母的前面(大写或小写字母之间不要求保持原来次序)
- (Relax 贪心1.4)POJ 2325 Persistent Numbers(使用贪心策略解决这么一个问题: 给定一个数n,求一个最小的数m,使得m的各位的乘积==n)
- 给定一个数组 a[n], 输出b[n], 其中 b[i] = a[0]*a[1]...*a[i-1]*a[i+1]*....a[n]; 其中不能用除法 复杂度要求O(n)