HDU 3377 插头dp
题目大意:
从左上角走到右下角,每个点之多经过一次,取到所有路径上经过点的权值,求最大的权值之和,这里走到右下角就算停止了
这里有个思路是转化成熟悉的回路问题
在上方和右方最外围定义一圈权值为0 , 那么我们相当于从定义以后的左上角开始经过所有外围点形成的回路,那么去掉最外围的0,剩下的就是(1,1)-》(n,n)的权值和了
但是这里最外围的点的插头具有特殊性,每次到最外围的点,你左和上有且仅有一个插头,而且出去的方向必然是下一个最外围的点
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 6 using namespace std; 7 #define ll long long 8 const int HASH = 10007; 9 const int STATE = 1000010; 10 const int MAXD = 15; 11 int n , m; 12 int code[MAXD] , mp[MAXD][MAXD]; 13 bool flag[MAXD][MAXD];//标记位,标记当前点能否作为最终点 14 ll ans = 0; 15 int w[MAXD][MAXD]; 16 struct HASHMAP{ 17 int head[HASH] , next[STATE] , state[STATE] , size; 18 ll f[STATE]; 19 20 void init(){ 21 size = 0; 22 memset(head , -1 , sizeof(head)); 23 } 24 25 void push_in(int st , ll sum){ 26 int h = st%HASH; 27 for(int i = head[h] ; ~i ; i=next[i]){ 28 if(st == state[i]){ 29 f[i]=max(f[i] , sum); //这题目为求最大值 30 return ; 31 } 32 } 33 f[size]=sum; 34 state[size] = st; 35 next[size] = head[h]; 36 head[h] = size++; 37 } 38 }hashmap[2]; 39 40 int num = 0;//记录共有的插头数量 41 void decode(int *code , int m , int st) 42 { 43 num = 0; 44 for(int i=m ; i>=0 ; i--){ 45 code[i] = st&3; 46 st>>=2; 47 if(code[i]) num++; 48 } 49 } 50 51 int encode(int *code , int m) 52 { 53 int st=0; 54 for(int i=0 ; i<=m ; i++){ 55 st<<=2; 56 st |= code[i]; 57 } 58 return st; 59 } 60 61 void shift(int *code , int m) //换行,可理解为将最右侧轮廓线换到了下一行的最左侧 62 { 63 for(int i=m ; i>=0 ; i--) code[i] = code[i-1]; 64 code[0] = 0; 65 } 66 67 void dpblank(int i , int j , int cur) 68 { 69 int k , left , up; 70 for(k=0 ; k<hashmap[cur].size ; k++){ 71 decode(code , m , hashmap[cur].state[k]); 72 left = code[j-1]; 73 up = code[j]; 74 if(!left && !up){ 75 if(mp[i][j]==2) continue; 76 if(mp[i][j]==1){ 77 if(j == m) shift(code , m); 78 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]); 79 } 80 if(mp[i][j+1] && mp[i+1][j]){ 81 code[j-1] = 1 , code[j] = 2; 82 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 83 } 84 } 85 else if(!left && up){ 86 if(mp[i][j]==2 && (up!=2)) continue; 87 else if(mp[i][j]==2){ 88 if(mp[i][j+1]==2) hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 89 else{ 90 code[j-1] = up , code[j] = 0; 91 if(j == m) shift(code , m); 92 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 93 } 94 continue; 95 } 96 if(mp[i][j+1]) hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 97 if(mp[i+1][j]){ 98 code[j-1] = up , code[j] = 0; 99 if(j == m) shift(code , m); 100 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 101 } 102 } 103 else if(left && !up){ 104 if(mp[i][j]==2 && (left!=2)) continue; 105 else if(mp[i][j]==2){ 106 if(mp[i][j+1]==2){ 107 code[j-1] = 0 , code[j] = left; 108 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 109 }else{ 110 if(j == m) shift(code , m); 111 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 112 } 113 continue; 114 } 115 if(mp[i+1][j]){ 116 if(j == m) shift(code , m); 117 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 118 } 119 if(mp[i][j+1]){ 120 code[j-1] = 0 , code[j] = left; 121 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 122 } 123 } 124 else if(mp[i][j]==2) continue; 125 else if(left==1 && up == 1){ 126 int cnt = 1; 127 for(int v=j+1 ; v<=m ; v++){ 128 if(code[v]==1)cnt++; 129 if(code[v]==2)cnt--; 130 if(!cnt){ 131 code[v]=1; 132 break; 133 } 134 } 135 code[j-1] = code[j] = 0; 136 if(j == m) shift(code , m); 137 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 138 } 139 else if(left == 2 && up == 2){ 140 int cnt=1; 141 for(int v=j-2 ; v>=1 ; v--){ 142 if(code[v]==2)cnt++; 143 if(code[v]==1)cnt--; 144 if(!cnt){ 145 code[v]=2; 146 break; 147 } 148 } 149 code[j-1] = code[j] = 0; 150 if(j == m) shift(code , m); 151 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 152 } 153 else if(left==1 && up==2){ 154 if(i==n && j==m) ans=max(ans,hashmap[cur].f[k]+w[i][j]); 155 } 156 else{ 157 code[j-1]=code[j]=0; 158 if(j == m) shift(code , m); 159 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]+w[i][j]); 160 } 161 } 162 } 163 164 void init() 165 { 166 for(int i=1 ; i<=m+1 ; i++) mp[1][i]=2 , w[1][i] = 0; 167 for(int i=2 ; i<=n+1 ; i++){ 168 for(int j=1 ; j<=m ; j++) 169 scanf("%d" , &w[i][j]) , mp[i][j]=1; 170 w[i][m+1] = 0 , mp[i][m+1] = 2; 171 mp[i][m+2] = mp[n+2][i]=0; 172 } 173 174 n++ , m++; 175 mp[1][1] = mp[n][m] = 1; 176 /*for(int i=1 ; i<=n ; i++){ 177 for(int j=1 ;j <=m ; j++){ 178 cout<<mp[i][j]<<" "; 179 } 180 cout<<endl; 181 }*/ 182 } 183 184 ll solve() 185 { 186 ans = -1e9; 187 int cur = 0; 188 hashmap[cur].init(); 189 hashmap[cur].push_in(0 , 0); 190 for(int i=1 ; i<=n ; i++){ 191 for(int j=1 ; j<=m ; j++){ 192 hashmap[cur^1].init(); 193 dpblank(i , j , cur); 194 cur ^= 1; 195 /* cout<<"test: "<<i<<" "<<j<<endl; 196 for(int k=0 ; k<hashmap[cur].size ; k++) 197 cout<<hashmap[cur].f[k]<<endl;*/ 198 199 } 200 } 201 // for(int i=0 ; i<hashmap[cur].size ; i++) 202 return ans; 203 } 204 205 int main() 206 { 207 // freopen("in.txt" , "r" , stdin); 208 int cas = 0; 209 while(~scanf("%d%d" , &n , &m)) 210 { 211 init(); 212 printf("Case %d: ",++cas); 213 if(n==1 && m==1){ 214 printf("%d\n" , w[1][1]); 215 continue; 216 } 217 printf("%I64d\n" , solve()); 218 } 219 return 0; 220 }
转载于:https://www.cnblogs.com/CSU3901130321/p/4730904.html
HDU 3377 插头dp相关推荐
- HDU1693 Eat The Trees(插头dp)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1693 Eat the Trees Time Limit: 4000/2000 MS (Java/Othe ...
- 插头DP题目泛做(为了对应WYD的课件)
题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. 1 #i ...
- 轮廓线DP(插头DP 裸 经典骨牌)
引言:所谓轮廓线,不是某一行,或者某一列,而是指某一个特定轮廓的状态. 放置骨牌的约定:(保证放置有最优子结构) 假设我们正在放置第i行的骨牌,那么会有下面3种方式: 灰色表示已经有的骨牌,绿色表示新 ...
- 好学易懂 从零开始的插头DP(三)
好学易懂 从零开始的插头DP(三) 写在前面 这篇文章主要是介绍一些括号表示法和简单回路的基本变化,下一篇会是一些非回路(最小表示),毒瘤状态(正wa着所以咕着),结合矩阵乘法加速等一些复杂应用.下下 ...
- bzoj1814 Ural 1519 Formula 1(插头dp模板题)
1814: Ural 1519 Formula 1 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 924 Solved: 351 [Submit][S ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...
- HDU4084 插头dp
题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...
- POJ3133(插头dp)
传送门:http://poj.org/problem?id=3133 Manhattan Wiring Time Limit: 5000MS Memory Limit: 65536K ...
- P3272 [SCOI2011]地板(插头DP)
[题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...
最新文章
- windows Azure
- 使用游戏测试干式EEG传感器的有效性
- 无效字符 java_Java知识查漏补缺
- GEMM算法及优化流程详解
- React之回调函数形式的ref
- 没有bug队——加贝——Python 练习实例 7,8
- 自己封装的Windows7 64位旗舰版,微软官网上下载的Windows7原版镜像制作,绝对纯净版...
- android java.net.ConnectException: Connection 127.0.0.1:8080 refused
- 通过自定义类加载器进行动态编译与动态实现接口
- ElasticSearch的优点
- Vivado:信道编码卷积编码和RS编码IP核
- 技术经理应该具备哪些方面的能力
- android 手机远程助手,安卓远程桌面软件
- 超详细的Python面向对象编程讲解
- python .center用法_python之testcenter操作
- 怎么看电脑是32位还是64位?超级简单的方法!
- Python廖雪峰教程学习笔记:Day4
- 七星彩长奖表图_2020海南七星彩奖表图最新
- 如何让DEDECMS织梦的TAGS标签静态化
- linux性能分析 -- top
热门文章
- 带你自学Python系列(四):range、min、max、sum函数
- 《Python编程从入门到实践》记录之input()函数
- 算法训练和模型部署如何避免多次重写数据预处理代码
- 弄潮儿数据_SINX 信息数据的“弄潮儿”
- 用python写helloworld_Python基于Tkinter的HelloWorld入门实例
- Docker 容器遇到的乱码问题
- 基于Web的浮动图片墙
- cisco 通过tftp备份/恢复配置和3560交换机IOS升级
- fast-planner 安装
- jQuery 中$('.classname').on('click',function(){});与$(document).on('click','.classname',function(){});