HDU
来源:互联网 发布:中国联通宽带提速软件 编辑:程序博客网 时间:2024/05/21 06:33
题意
在一张n*m的地图中,1表示有树,0表示没有树(也不能走)
DOTA中有一个英雄任务是去吃树(打防御塔)。问,他吃完所有树,并且相同地方不走两次的回路有几条(即哈密顿回路)。
思路
求哈夫曼回路,用插头dp
如果不知道插头dp,可以看看这里
参考代码
#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<cmath>using namespace std;int n,m;long long dp[15][15][1<<13]; // dp[行][列][状态] 里面的值代表 当前位置如果本状态 有多少方案数 int mp[15][15];int main(){ int t,ts=0; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&mp[i][j]); } } memset(dp,0,sizeof(dp)); dp[0][m][0]=1; for(int i=1;i<=n;i++){ //枚举每一行 for(int k=0;k<(1<<m);k++){ //初始化本行第零个元素 即加入第一个向右插头 dp[i][0][k<<1]=dp[i-1][m][k]; } for(int j=1;j<=m;j++){ //枚举本行的每个元素 int r=1<<j; // 用于检查向右的插头 int d=1<<(j-1); // 用于检查向下的插头 for(int k=0;k<(1<<m+1);k++){ //枚举可以的状态 if(mp[i][j]){ //有树要吃 if((r&k)&&(d&k)){ //有两个插头 dp[i][j][k]=dp[i][j-1][k-r-d]; // 没有插头传递过来 } else if((r&k)==0&&(d&k)==0){ // 没有插头 dp[i][j][k]=dp[i][j-1][k+r+d]; //说明 有两个插头传递过来 } else{ //有一个插头 dp[i][j][k]=dp[i][j-1][k^r^d]+dp[i][j-1][k]; // 传递一个插头 } } else{//没有树 if((r&k)==0&&(d&k)==0){ //没有插头 dp[i][j][k]=dp[i][j-1][k]; //无需传递插头 } else{ dp[i][j][k]=0; // 不可能有插头 } } } } } printf("Case %d: There are %lld ways to eat the trees.\n",++ts,dp[n][m][0]); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- JavaSE_异常处理
- 【库连接问题】makefile中如何连接库以及解决/usr/bin/ld: skipping incompatible问题
- 视频监控中运动物体检测与跟踪----相邻帧差法和三帧差法
- Ubuntu16.04安装tensorflow-gpu版
- Eclipse调试时出现source not found的问题
- HDU
- GetParentProcessId获取父进程ID
- AppIcon各种图片的生成使用Prepo工具快速便捷
- oom内存溢出解决方案
- 快速乘【模板】
- opencv学习笔记-5,绘制线条、矩形、圆、椭圆,添加文字
- 存储过程
- AI大行其道,你准备好了吗?—谨送给徘徊于转行AI的程序员
- C代码调用汇编&使用指令集优化