状压dp学习笔记
来源:互联网 发布:spring 源码书籍推荐 编辑:程序博客网 时间:2024/06/04 21:15
最近才开始学习状压dp,以前就听听没写过。到目前为止,我对状压dp的应用就是用数位表示点,通过枚举不同的数,也就是不同的到达状态,来实现状态的转移。跟着网上的博客切题中
1.POJ3254 Corn Fields
http://poj.org/problem?id=3254
做的第一个状压题,基本是跟着网上的思路写的,状压dp真是很神奇,通过位运算能解决很多问题。
#include<cstdio>#include<cstring>using namespace std;int ok[1<<13], each[1<<13], cnt;bool check(int x){ return (x&(x<<1));}bool check2(int x, int y){ return (ok[x]&each[y]);}int main(){ int m, n, a, dp[13][1<<13]; while(~scanf("%d%d", &m, &n)) { memset(dp, 0, sizeof(dp)); memset(each, 0, sizeof(each)); memset(ok, 0, sizeof(ok)); cnt=0; for(int i=1; i<=m; i++) { for(int j=1; j<=n; j++) { scanf("%d", &a); if(a==0) { each[i]+=(1<<(j-1)); } } // printf("each[%d]=%d\n", i, each[i]); } for(int i=0; i<(1<<n); i++) { if(!check(i)) ok[cnt++]=i; } for(int i=0; i<cnt; i++) { if(!check2(i, 1)) { dp[1][i]=1; } } for(int i=2; i<=m; i++) { for(int j=0; j<cnt; j++)//第i行当前处于j种取值 { if(check2(j, i))//如果第j种取值不符合规定 continue; for(int h=0; h<cnt; h++) //第i-1行当前处于h种取值 { if(check2(h, i-1)) continue; if(!(ok[j]&ok[h])) dp[i][j]+=dp[i-1][h]; } } } int ans=0; for(int i=0; i<cnt; i++) { ans+=dp[m][i]; ans%=100000000; } printf("%d\n", ans); } return 0;}
2.hdu 3001 Travelling
http://acm.hdu.edu.cn/showproblem.php?pid=3001
因为是最多经过两次,所以用三进制表示,因为习惯了二进制表示,一开始写的很丑而且都调不出bug。除了三进制之外,思路其实差不多。
#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>using namespace std;#define INF 0x1f1f1f1fint dis[15][15];int index[15] ;int record[60000][15];int dp[60000][15];void init_record(){ for(int i=0; i<59050; i++) { int t = i; for(int j = 1; j <= 10; ++j){ record[i][j] = t%3; t /= 3; if(t == 0)break; } } index[0]=0; index[1]=1; for(int i=2; i<=11; i++) { index[i]=index[i-1]*3; }}int main(){ int n, m, a, b, w; init_record(); while(~scanf("%d%d", &n, &m)) { memset(dis, INF, sizeof(dis)); for(int i=0; i<m; i++) { scanf("%d%d%d", &a, &b, &w); if(w<dis[a][b]) dis[a][b]=dis[b][a]=w; } memset(dp, INF, sizeof(dp)); int ans=INF; for(int state=1 ; state<index[n+1]; state++) { int flag=1; for(int i=1; i<=n; i++) { if(record[state][i]==0) { flag=0;continue; } if(state==index[i]) { dp[state][i]=0; continue; } for(int j=1; j<=n; j++) { if(i==j) continue; if(record[state][j]==0||dis[j][i]==INF) continue; int newstate=state-index[i]; dp[state][i]=min(dp[state][i], dp[newstate][j]+dis[j][i]); } } if(flag) { for(int j=1; j<=n; j++) ans=min(ans, dp[state][j]); } } if(ans==INF) printf("-1\n"); else printf("%d\n", ans); } return 0;}
。。。待续
阅读全文
0 0
- 状压dp学习笔记
- 状压DP学习笔记(一)
- 状压DP学习笔记(二)
- dp学习笔记
- dp学习笔记
- dp学习笔记1
- dp学习笔记2
- dp学习笔记3
- dp学习笔记4
- 树形dp学习笔记
- 斜率优化DP学习笔记
- 学习笔记:状态压缩DP
- 状态压缩 DP 学习笔记
- 斜率优化dp 学习笔记
- 斜率优化DP学习笔记
- 斜率优化dp学习笔记
- |算法讨论|状压DP/位运算 学习笔记
- NOIP专题复习(三) 状压DP学习笔记
- C++中clock用法
- Spring事务管理(详解+实例)
- NDK各个版本链接
- 7.分布式数据库HBase第3部分
- Android Studio 导入jar包 和 打包流程
- 状压dp学习笔记
- 码流 / 码率 / 比特率 / 帧速率 / 分辨率 / 高清的区别
- C++语言的函数重载、重写、覆盖的示例,及C++多态的两种方法
- CentOS OpenVAS的搭建
- 高性能场景下,HashMap的优化使用建议
- ubuntu 安装 jdk7
- ILMerge将winform程序打包成一个单文件可执行exe
- Complex Number Multiplication问题及解法
- android开发连接