一,状态压缩不讲了,很简单的;

二,讲讲最核心的算法,怎么算过来的;

a, 首先,动态规划是在求出子问题的基础上,并子问题不能变,在这个基础上,慢慢向后推,求出最终问题;

b, 难点就在这里,子问题是改变的,在这一行的数受到上一行和上上一行的影响,是改变的;

c, 但是在推到第3行时,表示第3行的状态时,包括第前2行,一起算到第3行,这样,在求第4行时,只需要看第4行的状态(包括第4行的前2行)的所用状态;

第3行的第一种状态的后二个状态数,与第4行的一种状态的前二个状态数匹配,成,就加上第4行的后一个状态数的炮的数量,进行求最大炮的数量;依次类推;

算完后,只要将最后一行的所有状态的炮的数量输出就好了;

三,我输出路径的方法;

每走一流程,到下一步,下一步,就会记录这一步的的位置;

这样,只要最后的位置,就可以反向推出一种方案;

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
const int N = 101;
const int M = 10;
int m,n;
int maze[N];
char arg[N][M];
int mazeAloneState[N][60];
int mazeAllState[N][216000][5];
int result,finish;
int minA,minB,minC;
int getNumber(int num){int count=0; int i;for(i=0; i<m; i++){if(num&(1<<i))count++;}return count;
}
int getSum(int n){if(n==0)  return 0;if(n>=59) return 4;if(n>=38) return 3;if(n>=11) return 2;if(n>=1)  return 1;
}
void showAll(int local){int i=0;if(local < 2) return;printf("*****************\n");while(mazeAllState[local][i][0] != -1){printf("%6d %6d %6d %6d %6d\n",mazeAllState[local][i][0], mazeAllState[local][i][1], mazeAllState[local][i][2], mazeAllState[local][i][3],mazeAllState[local][i][4] );i++; }printf("*****************");
}
void subA(){int i,j,k,max,temp,min;max = 0;for(i=59; i>=0; i--){if(mazeAloneState[0][i] != -1){temp = getSum(i);if(max<=temp){          max = temp;minA = i;}         }       }   result = max;
}
void subB(){    int i,j,max=0,temp;for(i=59; i>=0; i--){for(j=59; j>=0; j--){if(mazeAloneState[0][i]==-1 || mazeAloneState[1][j] == -1)continue;if( !( mazeAloneState[0][i] & mazeAloneState[1][j] ) ){                  temp = getSum(i) + getSum(j);if(max<=temp ){max = temp;minA=i;minB=j;}}            }}result = max;
}
void subC(){int i,j,k,max=0,temp,count = 0;for(i=59; i>=0; i--){for(j=59; j>=0; j--){for(k=59; k>=0; k--){if(mazeAloneState[0][i] == -1 || mazeAloneState[1][j] == -1 || mazeAloneState[2][k] == -1)continue;if(  !(mazeAloneState[0][i]&mazeAloneState[1][j])   &&  !(mazeAloneState[0][i]&mazeAloneState[2][k])&&  !(mazeAloneState[2][k]&mazeAloneState[1][j]) ) {                        temp = getSum(i) + getSum(j) + getSum(k);mazeAllState[2][count][0] = mazeAloneState[0][i];mazeAllState[2][count][1] = mazeAloneState[1][j];mazeAllState[2][count][2] = mazeAloneState[2][k];mazeAllState[2][count][3] = temp;mazeAllState[2][count][4] = 0;count++;if(max<=temp){max=temp;minA=i;minB=j;minC=k;}}}}}result = max;
}
void solveAll(){if(n<4) return ;int number = 3;while(number < n){int i,j,k,minA,minB,minC,max=0,temp,count = 0;for(i=59; i>=0; i--){for(j=59; j>=0; j--){for(k=59; k>=0; k--){if(mazeAloneState[number-2][i] == -1 || mazeAloneState[number-1][j] == -1 || mazeAloneState[number][k] == -1)continue;if(  !(mazeAloneState[number-2][i]&mazeAloneState[number-1][j])   &&  !(mazeAloneState[number-2][i]&mazeAloneState[number][k])&&  !(mazeAloneState[number][k]&mazeAloneState[number-1][j]) ) {                        temp = getSum(k);mazeAllState[number][count][0] = mazeAloneState[number-2][i];                                mazeAllState[number][count][1] = mazeAloneState[number-1][j];mazeAllState[number][count][2] = mazeAloneState[number][k];mazeAllState[number][count][3] = temp;mazeAllState[number][count][4] = 0;count++;if(max<=temp){max=temp;                                 }}}}}number++;}}
void getNext(int next[], int m){    int i,j;for(i=m-1,j=0; i>=0; i-- ){next[j++] = 1<<i;     }
}
void init(int n, int m){memset(maze, 0, sizeof(int)*N);memset(mazeAloneState, -1, sizeof(int)*N*60);memset(mazeAllState, -1, sizeof(int)*N*216000*5);int i,j,flag,temp;char ch;int *next = new int[m];getNext(next, m);for(i=0; i<n; i++){       for(j=0; j<m; j++){cin>>ch;arg[i][j] = ch; if(ch == 'H')maze[i]     += next[j];          }}  //初始化一行的状态 int count=0,a,b,c,h,k;  for(i=0; i<n; i++){mazeAloneState[i][0] = 0;count=1;for(j=0; j<m; j++){temp = 1<<j;if( !(temp&maze[i]) )mazeAloneState[i][count++] = temp;          }count=11;for(j=0; j<m; j++){for(k=j+3; k<m; k++){a = 1<<j; b = 1<<k;temp = a + b;                            if( !(temp&maze[i]) )mazeAloneState[i][count++] = temp;}}count=39;for(j=0; j<m; j++){for(k=j+3; k<m; k++){for(h=k+3; h<m; h++){a=1<<j; b=1<<k; c=1<<h;temp = a + b + c;                 if( !(temp&maze[i]) )mazeAloneState[i][count++] = temp;}}}count=59;     if( !(585&maze[i]) && m==10){mazeAloneState[i][count] = 585;}}solveAll();
}
void solve(){int i,j,k,count,temp,a,b,c,e,f;if(n==0){result = 0; return;}if(n==1){subA(); return;}if(n==2){subB(); return;}  if(n>=3){subC();            for(i=3; mazeAloneState[i][0] != -1; i++ ){         for(j=0; mazeAllState[i][j][0] != -1; j++){for(k=0; mazeAllState[i-1][k][0] != -1; k++){a = mazeAllState[i][j][0];b = mazeAllState[i][j][1];c = mazeAllState[i][j][2];temp = getNumber(c);                  e = mazeAllState[i-1][k][1];f = mazeAllState[i-1][k][2];if(a==e && b==f)if(mazeAllState[i-1][k][3]+temp > mazeAllState[i][j][3]){mazeAllState[i][j][3] = mazeAllState[i-1][k][3]+temp;mazeAllState[i][j][4] = k;   }                               }}}}    //找到最大值;int max = 0;for(i=0; mazeAllState[n-1][i][3] != -1; i++){   if( mazeAllState[n-1][i][3]>max ){max = mazeAllState[n-1][i][3];finish = i;}           }result = max;
}
void inputPath(){printf("\n***** 倒序 ******\n");if(n==1) {printf("path = %d\n",mazeAloneState[0][minA]);return ;}if(n==2){      printf("path = %d\n",mazeAloneState[1][minB]);printf("path = %d\n",mazeAloneState[0][minA]);return ;}if(n==3){printf("path = %d\n",mazeAloneState[2][minC]);printf("path = %d\n",mazeAloneState[1][minB]);printf("path = %d\n",mazeAloneState[0][minA]);return ;}int i,j,k,temp;for(i=n-1; i>=3; i--){printf("path = %d\n",mazeAllState[i][finish][2]);finish = mazeAllState[i][finish][4];}printf("path = %d\n",mazeAllState[i][finish][2]);printf("path = %d\n",mazeAllState[i][finish][1]);  printf("path = %d\n",mazeAllState[i][finish][0]);
}
int main()
{   cin>>n>>m;init(n,m);solve();printf("result = %d\n",result);inputPath();
}

POJ 1185(在求最大炮数上,输出一条方案,未Accept,网站在维护)相关推荐

  1. 求出千位数上的数加百位数上的数等于十位数上的数加个位数上的数的个数cnt,再把所有满足条件的四位数依次存入数组b中,然后对数组b中的四位数按从大到小的顺序进行排序。

    已知数据文件IN13.DAT中存有300个四位数,并已调用读函数readDat()把这些数存入数组a中,请编制一个函数jsValue(),其功能是:求出千位数上的数加百位数上的数等于十位数上的数加个位 ...

  2. 编制一个函数jsValue(),求出千位数上的数减百位数上的数减十位数上的数减个位数上的数大于零的个数cnt,再求出所有满足此条件的四位数的平均值pjz1,以及不满足此条件的四位数的平均值pzj2

    已知数据文件IN15.DAT中存有300个四位数,并已调用读函数readDat()把这些数存入数组a中,请编制一个函数jsValue(),其功能是:求出千位数上的数减百位数上的数减十位数上的数减个位数 ...

  3. POJ 1185 炮兵阵地(状态压缩DP)

    Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用&quo ...

  4. Bailian2701 Bailian3864 POJ NOI0105-39 与7无关的数【进制】

    问题链接:POJ NOI0105-39 与7无关的数. 问题链接:Bailian Bailian3864 与7无关的数. 总时间限制: 1000ms 内存限制: 65536kB 描述 一个正整数,如果 ...

  5. 【状态dp】poj 1185 炮兵阵地(三维dp)

    poj 1185 炮兵阵地 http://poj.org/problem?id=1185 问题描述:给你一个n行m列的P-H矩阵,H表示不能安置炮兵,1可以安置炮兵,要求炮兵攻击管辖内不能在安置其他炮 ...

  6. [递归]一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

    这题是用C写的~ 在牛客上半天找不着ACM模式,练习模式里只有核心代码模式 这样用C语言编译器就不能自定义函数啊,不鸡肋吗??? 解决方法:在核心代码模式下用C++编译器(反正C++完全兼容C的不是吗 ...

  7. 极限与连续知识点总结_高数上知识点期末复习 极限、连续、间断点(一)

    点击蓝字关注我们 No.1 函数 分值 题型解析1 题型解析2 tips: 为了帮助同学们更好的通过高数期末考试,不挂科,我们最近正在加紧制作<高等数学>上册的期末复习冲刺课程,包含讲解视 ...

  8. POJ NOI MATH-7830 求小数的某一位

    问题链接:POJ NOI MATH-7830 求小数的某一位. 总时间限制: 1000ms 内存限制: 65536kB 描述 分数a/b化为小数后,小数点后第n位的数字是多少? 输入 三个正整数a,b ...

  9. 【python逻辑算法题】一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法

    文章目录 一.题目描述 二.问题分析 三.代码分析与逻辑(python3实现) 四.源码及运行结果 总结 提示:以下是本篇文章正文内容: 一.题目描述 题目:一只青蛙一次可以跳上1级台阶,也可以跳上2 ...

最新文章

  1. Android保存图片到本地相册
  2. oracle9i的erp数据库无法正常关闭的解决方法。
  3. 使用 artTemplate 渲染数组
  4. python中randint用法_python中的randint,引入模块
  5. Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
  6. 黑苹果10.15.7安装comfast永存,CF-811AC驱动方法
  7. 我被开除了。。只因为看了骂公司的帖子
  8. 点互信息PMI(Pointwise Mutual Information)
  9. 拍摄须知ISO、快门、光圈、曝光概念
  10. Android 仿QQ好友列表功能实现
  11. 京东宙斯php版本sdk不能用_一个SDK引发的“血案”
  12. java中math.ceil用法_[Java教程]关于Math类的round、floor、ceil三个方法
  13. 完整性与完备性的区别
  14. 关于cmd输入字符长度限制问题
  15. 4.19 使用QT做上位机与下位机通讯
  16. 掘金技术社区沸点指南(试行版)
  17. linux shell脚本编写 | 三角形 | 梯形 | 菱形 | 九九乘法表 | 矩形 | 超详细
  18. Java比较日期时间大小
  19. win 32 APP 项目简单创建窗体
  20. Yocto Issues | The TMPDIR: /home12/calm.xia/poky/qemuarm/tmp can't be located on nfs.

热门文章

  1. mysql创建单个字段视图,MySQL在单表上创建视图
  2. Go内建容器——Golang学习笔记3
  3. Vue数据响应式原理:Observe、Dep、Watcher
  4. 软件调研:CSDN 问答 VS StackOverFlow
  5. 指称关系(Referring Relationships)
  6. excel拆分一列单元格为两列
  7. ZOJ 2770火烧连营——差分约束
  8. LeetCode(Python)—— x的平方根(简单)
  9. 项目验收汇报ppt_中煤天津设计公司举办2020年度项目汇报PPT技能大赛
  10. BJDCTF 2nd- -开场曲