POJ 1185
来源:互联网 发布:ui平面设计软件 编辑:程序博客网 时间:2024/05/16 05:07
这题的关键在于当前行的状态,怎么与上一行的状态进行匹配。
看到一个大神的解法,是用数组的下去匹配的;好6;
先说一下为什么可以这样做:(一行的,不包括二面二行的为方案,一行的包括二行的为状态)
一行的状态包括上面二行,然而这一行的状态只要保存这一行和上一行的方案下标,这时可以作为保存数量的下标的位置。
比如,这一行的是i方案,上一行的是j方案,那么以数组i,j为下标的二维数组存下当前方案的数量加上上一组对应的数组中的j,t 下标的数量。
上一行是jt,这一行是i,j;这是以对应的,是变化来的;只要模拟走一篇就懂了;
#include <iostream>#include <cstring>using namespace std;const int M=10,N=101;int n,m;int now[65],last[65],lastlast[65];int nowsize,lastsize,lastlastsize;int num[65];int temp[N][N],dp[N][N];char Map[N][M];int maze[N];void initAloneState(int local){int i,j,k,temp;for(i=0; i<m; ++i){if( (maze[local]&(1<<i)) ){continue;}now[++nowsize] = (1<<i);num[nowsize] = 1;}for(i = 0; i < m-3; ++i){for(j = i+3; j < m; ++j){if((maze[local]&(1<<i)) || (maze[local]&(1<<j))){continue;}now[++nowsize] = (1<<i) + (1<<j);num[nowsize] = 2;}}for(i = 0; i < m-6; ++i){for(j = i+3; j < m-3; ++j){for(k = j+3; k < m; ++k){if((maze[local]&(1<<i)) || (maze[local]&(1<<j)) || (maze[local]&(1<<k))){continue;}now[++nowsize] = (1<<i) + (1<<j) + (1<<k);num[nowsize] = 3;}}}if(m==10 && !(585&maze[local])){now[++nowsize] = 585;num[nowsize] = 4;}//cout<<endl;//int count = 0;//for(i = 0; i <= nowsize; ++i){//if(num[i] == 4){//printf("%d %d\n",num[i],now[i]);//count++;//}//}//printf("count = %d\n",count);}void DP(){int i,j,k,t;now[0] = 0;for(k=0; k<n; ++k){memset(now, 0, sizeof(int)*60);nowsize=0;initAloneState(k);for(i=0;i<=nowsize;++i)for(int j=0;j<=lastsize;++j)dp[i][j]=0; for(i=0;i<=nowsize;++i){//本行选择第几个方案 for(j=0;j<=lastsize;++j){//上一行选择第几个方案 for(t=0;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=0;i<=nowsize;++i)for(int j=0;j<=lastsize;++j)temp[i][j]=dp[i][j]; for(int i=0;i<=lastsize;++i)lastlast[i]=last[i];lastlastsize=lastsize; for(int i=0;i<=nowsize;++i)last[i]=now[i];lastsize=nowsize; }}void initMaze(){char str[10],ch;for(int i=0; i<n; ++i){scanf("%s",str);for(int j=0; j<m; ++j){ch = str[j];if(ch == 'H'){maze[i] += (1<<j);}} }}int main(){memset(maze, 0, sizeof(int)*N);scanf("%d %d",&n,&m);initMaze();last[0]=lastlast[0]=temp[0][0]=0; lastsize=lastlastsize=0;DP();int sum=0; for(int i=0;i<=lastsize;++i){ for(int j=0;j<=lastlastsize;++j){ if(temp[i][j]>sum)sum=temp[i][j]; } } printf("%d\n",sum); return 0;}
阅读全文
0 0
- POJ 1185
- poj 1185
- poj 1185
- poj 1185
- poj 1185
- poj 1185
- poj 1185
- poj 1185
- poj 1185
- poj-1185
- poj 1185
- POJ 1185
- poj 1185
- POJ 1185
- [状态压缩DP] Poj 3254, Poj 1185
- POJ 3254 & POJ 1185 (状态压缩DP)
- poj 1185 炮兵阵地
- POJ 1185 炮兵阵地
- android 自定义控件自定义属性
- 【Y分钟内迅速学会python3系列】 python学习记录 (二)
- Prophet(预言者)facebook时序预测----论文总结以及调参思路
- 如何判断DataFrame中是否有缺失值?
- 凸包的形成(C++双向循环链表描述)
- POJ 1185
- C#Arraylist集合的方法
- mysql开发技巧2
- 使用 Java 测试网络连通性的几种方法
- 03-创建测试脚本框架
- 性能杀手—伪共享
- 激活函数(relu,prelu,elu,+BN)对比on cifar10
- 20171030
- LeetCode之两数之和