状态压缩DP专题
来源:互联网 发布:dw给淘宝图片加链接 编辑:程序博客网 时间:2024/05/29 14:55
poj1038
题意:用2*3格子覆盖有禁区的n*m长方形,问最多可以放置多少个格子。
解法:整行覆盖,第二维存储前两行的覆盖状态
dp[i][st]:前i-1行已覆盖完成,且i-1,i-2行的覆盖状态为st,最多可以放置的格子数
状态设计用三进制存储:
0:前两行均无覆盖
1:i-2行覆盖,i-1行无覆盖
2:i-1行覆盖
枚举时从第0列开始,分三种情况:
1.不填充该格
2.横放2*3格子,以该格为右上角
3.竖放2*3格子,以该格为右上角
然后进行dfs,直到枚举到最后一列,得到最终状态st’,进行状态转移即可
# include<iostream># include<cstdio># include<algorithm># include<queue># include<complex># include<stack># include<math.h># include<cstring>#include<map>#define ll long long#define pi acos(-1)#define MP make_pair#define X first#define Y secondusing namespace std;const int INF = 0x3f3f3f3f;const int maxn = 150+10;const int maxm = 10+10;const int maxst = 60000;int t,n,m;int dp[3][maxst];bool ma[maxn][maxm];int bit[maxm];int three[maxm],ans,cur;void init(){ three[0]=1; for(int i=1;i<=11;i++) three[i]=three[i-1]*3;}void fenjie(int x,int &y){ for(int i=0;i<m;i++){ bit[i]=x%3; if(bit[i]!=0) y+=three[i]*(bit[i]-1); x/=3; }}bool d1(int r,int c){//横放地图限制 if(ma[r][c]||ma[r][c+1]||ma[r-1][c]||ma[r-1][c+1]||ma[r-2][c]||ma[r-2][c+1]) return false; return true;}bool d2(int r,int c){//竖放地图限制 if(ma[r][c]||ma[r-1][c]||ma[r][c+1]||ma[r-1][c+1]||ma[r][c+2]||ma[r-1][c+2]) return false; return true;}void update(int row,int nowc,int now,int num){ if(nowc>=m){ dp[cur][now]=max(dp[cur][now],num); return; } if(row-2>=0&&nowc+1<m&&bit[nowc]==0&&bit[nowc+1]==0&&d1(row,nowc)){//可以横放 update(row,nowc+2,now+three[nowc]*2+three[nowc+1]*2,num+1); } if(row-1>=0&&nowc+2<m&&bit[nowc]!=2&&bit[nowc+1]!=2&&bit[nowc+2]!=2&&d2(row,nowc)){//可以竖放 update(row,nowc+3,now+three[nowc]*2+three[nowc+1]*2+three[nowc+2]*2,num+1); } update(row,nowc+1,now,num);//不放}int main(){ init(); //freopen("a.txt","r",stdin); scanf("%d",&t); while(t--){ int num; scanf("%d%d%d",&n,&m,&num); memset(ma,0,sizeof(ma)); for(int i=1;i<=num;i++){ int x,y; scanf("%d%d",&x,&y); x--,y--; ma[x][y]=1; } //第一列不放 for(int i=0;i<maxst-3;i++) dp[0][i]=-INF; dp[0][0]=0; cur=0; //从第二列开始放置 ans=0; for(int i=1;i<n;i++){ cur^=1; for(int j=0;j<maxst;j++) dp[cur][j]=-INF; for(int j=0;j<three[m];j++){//注意枚举上界不再是(1<<M),不能使用位运算! if(dp[1-cur][j]==-INF) continue; int k=0; fenjie(j,k); dp[cur][k]=max(dp[cur][k],dp[1-cur][j]);//整行不放 update(i,0,k,dp[1-cur][j]); } } for(int i=0;i<three[m];i++) ans=max(ans,dp[cur][i]); printf("%d\n",ans); } return 0;}
zoj1346
题意:DAG图拓扑排序的个数统计
解法:dp[st]表示还有st状态的点未加入序列时,还能够有的排序方法数
删除已加入的点及相关边,然后枚举当前入度为0的点,加入st状态,记忆化搜索即可
复杂度分析:
# include<iostream># include<cstdio># include<algorithm># include<queue># include<complex># include<stack># include<math.h># include<cstring>#include<map>#define ll long long#define pi acos(-1)#define MP make_pair#define X first#define Y secondusing namespace std;const int maxn = (1<<18);int n,cnt;map<string,int> ma;char ch1[20],ch2[20];int du[20];int vis[20][20];ll dp[maxn];ll dfs(int st){ if(dp[st]!=-1) return dp[st]; int tmpdu[20]; ll tmp=0; for(int j=0;j<cnt;j++) tmpdu[j]=du[j]; for(int i=0;i<cnt;i++){//删点 减度 if(st&(1<<i)){ for(int j=0;j<cnt;j++) if(vis[i][j]){ tmpdu[j]--; } } } for(int j=0;j<cnt;j++) if(!(st&(1<<j))&&!tmpdu[j]){ tmp+=dfs(st|(1<<j)); } return dp[st]=tmp;}int main(){ //freopen("a.txt","r",stdin); while(scanf("%d",&n)!=EOF){ ma.clear(); cnt=0; memset(du,0,sizeof(du)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ scanf("%s%s",ch1,ch2); if(ma.find(string(ch1))==ma.end()) ma[string(ch1)]=cnt++; if(ma.find(string(ch2))==ma.end()) ma[string(ch2)]=cnt++; int u=ma[string(ch1)],v=ma[string(ch2)]; vis[u][v]=1; du[v]++; } memset(dp,-1,sizeof(dp)); dp[(1<<cnt)-1]=1; dfs(0); printf("%lld\n",dp[0]); } return 0;}
0 0
- 状态压缩DP专题
- [POJ] 状态压缩DP专题
- poj 3254(状态压缩dp专题)
- 动态规划专题:树上DP和状态压缩DP
- [dp专题-状态压缩dp] 51nod 1033
- 状态压缩dp
- pku1038状态压缩dp
- 状态压缩DP 入门
- HDU1074 状态压缩DP
- Poj3254 状态压缩DP
- 状态压缩DP入门
- 【状态压缩DP】互不侵犯
- 【状态压缩DP】电子竞技
- HDU1074 状态压缩DP
- 【状态压缩DP】互不侵犯
- 状态压缩 DP AHU420
- HDU2167 状态压缩DP
- SGU223 -状态压缩DP
- Fence Repair
- Hadoop2.2.0安装配置手册!完全分布式Hadoop集群搭建过程~(心血之作啊~~)
- ARM汇编指令
- Tomcat异常之 Exception loading sessions from persistent storage解决方案
- 1032. Sharing (25)
- 状态压缩DP专题
- 2 Add Two Numbers
- Mac 终端命令运行java程序
- 举例解释对抽象类和接口的理解
- EmgnCv进行轮廓寻找和计算物体凸包
- Android NDK开发环境搭建
- c语言运算符号详细说明
- 对onreadystatechange属性的理解
- C# 窗体中 webbrowser 中 javascript 调用窗体方法 实例