poj1321 棋盘问题(状态压缩)
来源:互联网 发布:淘宝宝贝描述用什么做 编辑:程序博客网 时间:2024/05/21 01:30
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 对于每一组数据,给出一行输出,输出摆放的方案数目#..#4 4...#..#..#..#...-1 -1
Sample Output
21
Source
蔡错@pku
[Submit] [Go Back] [Status] [Discuss]
/*非常棒的解法:状态压缩DP!!关键点:1.(j&(1<<(u-1)))==0)的判断决定了dp[i][j]是否=0 即有.(不可放旗位子)时,它决定了在#可以放,即dp[i][j]不为02.这里的二进制是倒过来的ex:一般是3=011;这里3=110 因为要与图配合+方便表示(当然你也可以把它弄成一般的(1<<(u-1))改成(1<<(n-u))即可//*/#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define NN 300int ill[12][NN],num[NN];int dp[12][NN];//dp[i][j]:1到i行已覆盖j列的方案数int i,j,l,n,k,status,newst,ans,u;char g[12][12];void cal(int now){ int i,j,tmp,flag,cnt; tmp=1; cnt=0; for(i=1;i<=n;++i){ if (now&tmp) cnt+=1; tmp=tmp<<1; } num[now]=cnt; }void pbinary(int tj){int flag=0,bn=tj;while(tj){if(tj&1)cout<<1;else cout<<0;tj/=2;flag++;}while(flag<n){cout<<0; flag++;}cout<<" ---> "<<bn<<endl;}int main(){//freopen("in.h","r",stdin); while(1){ scanf("%d%d",&n,&k); if (n==-1&&k==-1) break; for(i=1;i<=n;++i) scanf("%s",g[i]+1); status=1<<n; for(i=0;i<status;++i) cal(i);//num[i]存的是i对应2进制的1的位数(即表已经放了num[i]个旗子在棋盘)//代表的是每一行可以放的状态.如n=2有4种状态(用0~3的二进制表示) //for(i=0;i<status;++i) cout<<num[i]<<" ";cout<<endl; memset(dp,0,sizeof(dp)); dp[0][0]=1; for(i=1;i<=n;++i){ for(j=0;j<status;++j)if (num[j]<=k)//(棋盘已放num[j]个旗子<=要放){ dp[i][j]+=dp[i-1][j];//+=:下面产生的或会影响f[i][j]//当前行不加棋子(也相当于把上次状态转移到当前)//若上一行的j状态还未出现,则有dp[i-1][j]=0 for(u=1;u<=n;++u)if ((g[i][u]=='#')&&(j&(1<<(n-u)))==0){//(1<<(u-1))表把第u位转为二进制,比如:u=3;(1<<(u-1))=4即二进制100倒数第3个(即第一个)为1//目的是和状态j(1表已放位置)的二进制比较,看是否不在同列 //newst=j|(1<<(u-1));newst=j|(1<<(n-u));dp[i][newst]+=dp[i-1][j];/*pbinary(j);pbinary(1<<(u-1));pbinary(newst);//*///若上一行的j状态还未出现,则有dp[i-1][j]=0//当前行加棋子,由j状态到newst状态,故f[i-1,j]+到f[i,newst] } } } for(ans=i=0;i<status;++i) if (num[i]==k) {ans+=dp[n][i];}//最后将最后一行棋子数等于k的状态的方案数求和即可。 printf("%d\n",ans); } return 0;}//c框from:http://blog.csdn.net/asdfgh0308/article/details/8454022
</pre><pre name="code" class="cpp">网上满天下的dfs,这里就不多说了
<pre name="code" class="cpp">#include<iostream>#include<cstdio>#include<cstring>using namespace std;int n,m,ans,flag;int vis[11][11],a[11][11],c[11];char s[11][11];void dfs(int x,int de){if(de==m){flag++;return ;}int i,j;for(i=x+1;i<=n;i++)//防止一行都不是旗位{for(j=1;j<=n;j++){if(c[j] || a[i][j]==0)continue;c[j]=1; //放dfs(i,de+1);c[j]=0; //不放}}}int main(){int i,j;while(~scanf("%d%d",&n,&m)){if(n==-1 && m==-1)break;memset(c,0,sizeof(c));memset(a,0,sizeof(a));flag=0;for(i=1;i<=n;i++){scanf("%s",s[i]);for(j=0;j<strlen(s[i]);j++)if(s[i][j]=='#')a[i][j+1]=1;}dfs(0,0);printf("%d\n",flag);}return 0;}
0 0
- poj1321 棋盘问题(状态压缩)
- poj1321 棋盘问题,状态压缩dp
- 棋盘问题(POJ1321)
- poj1321——棋盘问题——————【状态压缩、动态规划】
- POJ1321 棋盘问题(DFS)
- poj1321--棋盘问题(DFS)
- poj1321棋盘问题(深搜)
- poj1321 棋盘问题(DFS)
- POJ1321 棋盘问题(DFS)
- POJ1321 棋盘问题(dfs)
- POJ1321 棋盘问题(dfs)
- poj1321棋盘问题(DFS)
- poj1321棋盘问题(dfs)
- poj1321棋盘问题(dfs)
- 棋盘问题(poj1321)dfs
- poj1321 棋盘问题 (dfs)
- poj1321-棋盘问题(深搜)
- POJ1321棋盘问题(DFS)
- zf2 redis 练手2
- linux-centos-使用学习
- MFC视图切换全总结(图文)
- J2EE概念综述
- python numpy,matplotlib,setuptools windows环境下的安装
- poj1321 棋盘问题(状态压缩)
- 常见HTTP状态码整理
- Oracle特殊字符转义:&和'
- K均值算法
- html5桌面通知(Web Notifications)实例解析
- C语言之逗号运算符、自动转换和强制转换
- 每日一句【2015-01-17】
- 客户端开发注意事项
- gcc生成静态库和动态库