标签:
题目大意:
从左上角走到右下角,每个点之多经过一次,取到所有路径上经过点的权值,求最大的权值之和,这里走到右下角就算停止了
这里有个思路是转化成熟悉的回路问题
在上方和右方最外围定义一圈权值为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 }
标签:
原文地址:http://www.cnblogs.com/CSU3901130321/p/4730904.html