首页 > 代码库 > POJ 1185(状态压缩原来还可以这样)
POJ 1185(状态压缩原来还可以这样)
吐槽一下,刚做完两个状压的题,想着是一样的思路。没想到被坑了
有点类似于图论题目中不用邻接矩阵而用存储点将数据规模从输入范围->输入量
刚开始看题以为是攻击范围也不能重合,于是就是考虑到4次的范围。然后就是i-1,j-2两行如何组合而成。
果断TLE,如果用dp[maxn][1<<10][1<<10],MLE,TLE。
其实换个思路,10个方格的组合情况其实至多就只有60种,可以换成存储个数。
不吐槽了,贴一个代码。懒得自己写了。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <map> #include <cmath> #include <iomanip> #define INF 99999999 typedef long long LL; using namespace std; const int MAX=100+10; int n,m,lastsize,lastlastsize,nowsize; int last[MAX],lastlast[MAX],now[MAX]; int num[MAX],dp[MAX][MAX],temp[MAX][MAX];//dp[k][i][j]表示第k行选择i方案,第k-1行选择j方案的最大炮兵数 char Map[MAX][MAX]; void dfs(int id,int k,int p,int sum){ if(k>=m){now[++nowsize]=p;num[nowsize]=sum;return;} if(Map[id][k] == 'P')dfs(id,k+3,p|(1<<k),sum+1); dfs(id,k+1,p,sum); } void DP(){ for(int k=1;k<=n;++k){ memset(now,0,sizeof now); nowsize=0; dfs(k,0,0,0); for(int i=1;i<=nowsize;++i)for(int j=1;j<=lastsize;++j)dp[i][j]=0; for(int i=1;i<=nowsize;++i){//本行选择第几个方案 for(int j=1;j<=lastsize;++j){//上一行选择第几个方案 for(int t=1;t<=lastlastsize;++t){//上上行选择第几个方案 if(now[i] & last[j])continue;//与上一行j方案不能共存 if(now[i] & lastlast[t])continue;//与上上行t方案不能共存 if(dp[i][j]<temp[j][t]+num[i])dp[i][j]=temp[j][t]+num[i]; } } } for(int i=1;i<=nowsize;++i)for(int j=1;j<=lastsize;++j)temp[i][j]=dp[i][j]; for(int i=1;i<=lastsize;++i)lastlast[i]=last[i];lastlastsize=lastsize; for(int i=1;i<=nowsize;++i)last[i]=now[i];lastsize=nowsize; } } int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;++i)scanf("%s",Map[i]); last[1]=lastlast[1]=temp[1][1]=0; lastsize=lastlastsize=1; DP(); int sum=0; for(int i=1;i<=lastsize;++i){ for(int j=1;j<=lastlastsize;++j){ if(temp[i][j]>sum)sum=temp[i][j]; } } printf("%d\n",sum); } return 0; }
POJ 1185(状态压缩原来还可以这样)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。