给定一个m行n列的矩阵,你可以从任意位置开始取数,到达任意位置都可以结束,每次可以走到的数是当前这个数上下左右的邻居之一,唯一的限制是每个位置只能经过一次,也就是说你的路径不自交。所经过的数的总作为你的得分,求最大的得分。
Input
第一行两个整数m, n (0 < m, n < 10),表示矩阵的行数和列数。
后面m行,每行n个整数表示矩阵里的数,整数范围[-10000000, +10000000]。
Output
一个整数表示最大得分。

插头dp,状态可以用滚动数组存

#include<cstdio>
#include<cstring>
int n,m;
int v[][];
int s0[+],s1[+];
bool po[];
const int v0=-;
inline void maxs(int&a,int b){if(a<b)a=b;}
inline int _l(int x,int w){
int t=,a;
do{
w-=;
a=x>>w&;
t+=(a>>)-(a&);
}while(t);
return w;
}
inline int _r(int x,int w){
int t=,a;
do{
w+=;
a=x>>w&;
t-=(a>>)-(a&);
}while(t);
return w;
}
int main(){
scanf("%d%d",&n,&m);
int ans=v0;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
scanf("%d",v[i]+j);
if(v[i][j]>ans)ans=v[i][j];
}
}
if(ans<=)return printf("%d\n",ans),;
int mx=<<*(m+);
for(int i=;i<mx;++i){
int t=;
for(int j=;j<=m;++j)t+=((i>>j*&)==);
po[i]=(t<=);
}
for(int i=;i<mx;++i)s1[i]=v0;
s1[]=;
for(int i=;i<=n+;++i){
for(int j=;j<=m;++j){
for(int p=;p<mx;++p){
s0[p]=s1[p];
s1[p]=v0;
}
for(int p=;p<mx;++p)if(s0[p]!=v0&&po[p]){
int tt=;
for(int t=;t<=m;++t)tt+=(p>>t*&)+(p>>t*+&);
bool is=(tt==);
if(is)maxs(ans,s0[p]);
int p1=j*-,p2=j*;
int a=p>>p1&,b=p>>p2&,c=s0[p]+v[i][j],d1=~(<<j*-),d2=~(<<j*);
switch(a){
case :{
switch(b){
case :{
maxs(s1[p],s0[p]);
maxs(s1[p|<<p2],c);
maxs(s1[p|<<p1],c);
maxs(s1[p|<<p1|<<p2],c);
break;
}
case :{
maxs(s1[p],c);
maxs(s1[p&d2|<<p1],c);
maxs(s1[p&d1&d2|<<_r(p,p2)],c);
break;
}
case :{
maxs(s1[p],c);
maxs(s1[p&d2|<<p1],c);
maxs(s1[p&d1&d2|<<_l(p,p1)],c);
break;
}
case :{
maxs(s1[p],c);
maxs(s1[p&d2|<<p1],c);
break;
}
}
break;
}
case :{
switch(b){
case :{
maxs(s1[p&d1|<<p2],c);
maxs(s1[p],c);
maxs(s1[p&d1|<<_r(p,p2)],c);
break;
}
case :{
maxs(s1[p&d1&d2^<<_r(p,p2)],c);
break;
}
case :{
maxs(s1[p&d1&d2|<<_r(p,p2)],c);
break;
}
}
break;
}
case :{
switch(b){
case :{
maxs(s1[p&d1|<<p2],c);
maxs(s1[p],c);
maxs(s1[p&d1|<<_l(p,p1)],c);
break;
}
case :{
maxs(s1[p&d1&d2],c);
break;
}
case :{
maxs(s1[p&d1&d2^<<_l(p,p1)],c);
break;
}
case :{
maxs(s1[p&d1&d2|<<_l(p,p1)],c);
break;
}
}
break;
}
case :{
switch(b){
case :{
maxs(s1[p&d1|<<p2],c);
maxs(s1[p],c);
break;
}
case :{
maxs(s1[p&d1&d2|<<_r(p,p2)],c);
break;
}
case :{
maxs(s1[p&d1&d2|<<_l(p,p1)],c);
break;
}
case :{
if(tt==)maxs(ans,c);
break;
}
}
break;
}
}
}
if(i==n+)break;
}
for(int a=mx-;a>=;a-=){
s1[a+]=s1[a+]=s1[a+]=v0;
s1[a]=s1[a>>];
}
}
printf("%d",ans);
return ;
}

51nod 1411 矩阵取数问题 V3的更多相关文章

  1. 51Nod 1083 矩阵取数问题(矩阵取数dp,基础题)

    1083 矩阵取数问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下 ...

  2. 51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1084 1084 矩阵取数问题 V2  基准时间限制:2 秒 空 ...

  3. 51nod动态规划-----矩阵取数

    一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值. 例如:3 * 3的方格. 1 3 3 2 1 3 2 2 1 能够获得的最 ...

  4. 51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化

    基准时间限制:2 秒 空间限制:131072 KB  一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向 ...

  5. 51nod 1083 矩阵取数问题【动态规划】

    一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值. 例如:3 * 3的方格. 1 3 3 2 1 3 2 2 1 能够获得的最 ...

  6. 51nod 1083 矩阵取数问题

    就很简单很简单的dp 只能从右或者从下走 所以  dp方程直接看下面公式吧  反正也不难 #include<bits/stdc++.h> using namespace std; ; in ...

  7. 51Nod 1083 矩阵取数问题 | 动态规划

    #include "bits/stdc++.h" using namespace std; #define LL long long #define INF 0x3f3f3f3f3 ...

  8. 51Nod 1084:矩阵取数问题 V2(多维DP)

    1084 矩阵取数问题 V2  基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励 ...

  9. 51nod 更难的矩阵取数问题(动态规划)

    更难的矩阵取数问题 给定一个m行n列的矩阵,矩阵每个元素是一个正整数,你现在 在左上角(第一行第一列),你需要走到右下角(第m行,第n列),每次只能朝右或者下走到相邻的位置,不能走出矩阵.然后再从右下 ...

随机推荐

  1. hadoop常用基础命令

    1.日志查询: 用户可使用以下命令在指定路径下查看历史日志汇总$ bin/hadoop job -history output-dir 这条命令会显示作业的细节信息,失败和终止的任务细节. 关于作业的 ...

  2. How to adjust OOM score for a process?

    转载自http://www.dbasquare.com/kb/how-to-adjust-oom-score-for-a-process/ How to adjust OOM score for a ...

  3. 如何优雅的写C++代码(一)

    // get the greatest power of two that is a divisor of n: return n&-n; // swap two integers a and ...

  4. bootStrap-1

    bootstrap是什么? 1.简单灵活可用于架构流行的用户界面和交互借口的Html.css/javascript工具集. 2.基于html5.css3的bootstrap,具有大量的诱人特性:友好的 ...

  5. leetcode 137. Single Number II ----- java

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  6. 黑马程序员——JAVA基础之异常处理机制

    ------- android培训.java培训.期待与您交流! ---------- 异常:就是程序在运行时出现不正常情况. 异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式 ...

  7. feature visualization from ipython notebook

    Feature visualization from ipython notebook Wang Xiao 1. install anaconda2 from: https://www.continu ...

  8. memory dump and CLR Inside Out

    MSDN Magazine: CLR Inside Out https://msdn.microsoft.com/en-us/magazine/cc501040.aspx CLR Inside Out ...

  9. soap的简单实现(PHP)

    1.非wsdl模式 (1)函数文件 testphp/ServiceFunctions.class.php <?php /** * @author 左小兵 * */ class ServiceFu ...

  10. Android 反编译 代码注入之HelloWorld

    为了向经典的"Hello, World"致敬,我们也从一个简单的程序开始HelloWorld.apk.当你把这个APK安装到手机上运行后,在屏幕上就显示一行文字"Hell ...