Aizu 2538 Stack Maze【记忆化搜索】
2015-09-15 21:24
477 查看
其实我并不知道我的姿势算是什么。
一开始想着用二维的记忆化搜索,用dp[x][y]dp[x][y]表示(x,y)→(H,W)(x,y)\rightarrow(H,W)能够得到的最大happy值。但是很遗憾的是,这样没法记录,在前进的路上,我有多少个宝石、能够经过多少宝石洞。
所以就想着如何记录,最后发现难以记录。如果是这样的记忆化搜索,时间复杂度大约是O(n2)O(n^2),那么就想着可以进行扩大时间复杂度的算法。大约估算了一下504=625000050^4=6250000,可以做。
于是最终想到了记录起点和终点的方法。
用类似与区间dp的方式来计算。
记录每一种洞的位置,或者记录每个宝石可以填到那些洞里,那么就可以将区间分成(1,1)→(xx,yy)→(x,y)→(H,W)(1,1)\rightarrow(xx,yy)\rightarrow(x,y)\rightarrow(H,W),其中(xx,yy)(xx,yy)为宝石的所在地,(x,y)(x,y)为宝石洞的所在地。如果成功走过去了就可以将区间答案+1。
注意一下如果区间{l⃗ ,r⃗ }\{\vec{l},\vec{r}\}的特判情况,如果l⃗ ≥r⃗ \vec{l}\geq \vec{r}则返回0,如果l⃗ ≤r⃗ \vec{l}\leq \vec{r}且l⃗ \vec{l}不可到达r⃗ \vec{r}则返回−∞-\infty
一开始想着用二维的记忆化搜索,用dp[x][y]dp[x][y]表示(x,y)→(H,W)(x,y)\rightarrow(H,W)能够得到的最大happy值。但是很遗憾的是,这样没法记录,在前进的路上,我有多少个宝石、能够经过多少宝石洞。
所以就想着如何记录,最后发现难以记录。如果是这样的记忆化搜索,时间复杂度大约是O(n2)O(n^2),那么就想着可以进行扩大时间复杂度的算法。大约估算了一下504=625000050^4=6250000,可以做。
于是最终想到了记录起点和终点的方法。
用类似与区间dp的方式来计算。
记录每一种洞的位置,或者记录每个宝石可以填到那些洞里,那么就可以将区间分成(1,1)→(xx,yy)→(x,y)→(H,W)(1,1)\rightarrow(xx,yy)\rightarrow(x,y)\rightarrow(H,W),其中(xx,yy)(xx,yy)为宝石的所在地,(x,y)(x,y)为宝石洞的所在地。如果成功走过去了就可以将区间答案+1。
注意一下如果区间{l⃗ ,r⃗ }\{\vec{l},\vec{r}\}的特判情况,如果l⃗ ≥r⃗ \vec{l}\geq \vec{r}则返回0,如果l⃗ ≤r⃗ \vec{l}\leq \vec{r}且l⃗ \vec{l}不可到达r⃗ \vec{r}则返回−∞-\infty
[code]// whn6325689 // Mr.Phoebe // http://blog.csdn.net/u013007900 #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> #include <functional> #include <numeric> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define eps 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LLINF 1LL<<50 #define speed std::ios::sync_with_stdio(false); typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<ll, ll> pll; typedef complex<ld> point; typedef pair<int, int> pii; typedef pair<pii, int> piii; typedef vector<int> vi; #define CLR(x,y) memset(x,y,sizeof(x)) #define CPY(x,y) memcpy(x,y,sizeof(x)) #define clr(a,x,size) memset(a,x,sizeof(a[0])*(size)) #define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size)) #define debug(a) cout << #a" = " << (a) << endl; #define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; } #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define lowbit(x) (x&(-x)) #define MID(x,y) (x+((y-x)>>1)) #define ls (idx<<1) #define rs (idx<<1|1) #define lson ls,l,mid #define rson rs,mid+1,r template<class T> inline bool read(T &n) { T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true; } template <class T> inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48); } //----------------------------------- const int dir[2][2] = {1,0,0,1}; char ma[55][55]; int dp[55][55][55][55]; int g[55][55][55][55]; int h,w; vector<pii> hole[26]; bool in(int x,int y) { return x>=1 && x<=h && y>=1 && y<=w && ma[x][y]!='#'; } int dfs(int px,int py,int x,int y) { if(~dp[px][py][x][y]) return dp[px][py][x][y]; if(x<px || y<py) return dp[px][py][x][y]=0; if(x==px && y==py) return dp[px][py][x][y]=0; if(!g[px][py][x][y]) return dp[px][py][x][y]=-INF; int ret=0; if(ma[px][py]>='a' && ma[px][py]<='z') { int je=ma[px][py]-'a'; for(int k=0; k<hole[je].size(); k++) { int nx=hole[je][k].first; int ny=hole[je][k].second; if(px<=nx && py<=ny && nx<=x && ny<=y && g[px][py][nx][ny] && g[nx][ny][x][y]) { for(int i=0; i<2; i++) { int xx=px+dir[i][0]; int yy=py+dir[i][1]; if(in(xx,yy)) { if(in(nx-1,ny)) ret=max(ret,dfs(xx,yy,nx-1,ny)+1+dfs(nx,ny,x,y)); if(in(nx,ny)) ret=max(ret,dfs(xx,yy,nx,ny-1)+1+dfs(nx,ny,x,y)); } } } } } for(int i=0; i<2; i++) { int xx=px+dir[i][0]; int yy=py+dir[i][1]; if(in(xx,yy) && g[xx][yy][x][y]) ret=max(ret,dfs(xx,yy,x,y)); } return dp[px][py][x][y]=ret; } void init() { CLR(dp,-1); CLR(g,0); for(int i=0; i<26; i++) hole[i].clear(); } int main() { freopen("data.txt","r",stdin); while(read(h)&&read(w)&&(w+h)) { init(); for(int i=1; i<=h; i++) { scanf("%s",ma[i]+1); for(int j=1; j<=w; j++) if(ma[i][j]<='Z' && ma[i][j]>='A') hole[ma[i][j]-'A'].pb(mp(i,j)); } for(int i=h; i>=0; i--) for(int j=w; j>=0; j--) { if(ma[i][j]=='#') continue; for(int k=0; k<2; k++) { int xx=i+dir[k][0]; int yy=j+dir[k][1]; if(!in(xx,yy)) continue; for(int x=xx; x<=h; x++) for(int y=yy; y<=w; y++) g[i][j][x][y]|=g[xx][yy][x][y]; } g[i][j][i][j]=1; } int ans=dfs(1,1,h,w); if(ans==-INF) printf("%d\n",-1); else printf("%d\n",ans); } return 0; }
相关文章推荐
- Adb fail to restart! ADB server didn't ACK
- 【STL】STL之pair
- 怎么理解SpriteKit中的waitForDuration:withRange:方法
- Corsair DOMINATOR Platinum 海盗船3300MHz C16 DDR4 4GB*4 内存条 $336.77 国行售价¥5000+
- [Leetcode]Paint House II
- grails 事务 Transactional
- 解决Failed to load class "org.slf4j.impl.StaticLoggerBinder"
- sqrt和Hailstone
- sleep、yield、wait知识点
- mmap例子详解 http://blog.csdn.net/eroswang/article/details/1908842
- Number of Airplanes in the Sky
- MongoDB性能篇 -创建索引,组合索引,唯一索引,删除索引和explain执行计划
- Light oj 1071 - Baker Vai(记忆化)
- codeforces #576E Painting Edges 分治+并查集
- failed to update auto layout status: the agent crashed within Xcode7
- API介绍:iBeacons、Sprite Kit、Game Center以及AirDrop等
- 用<%# DataBinder.Eval(Container.DataItem,"ID")%>显示数据的,标题太长规定字数,多余的用"..."
- Linux(C/C++)下的文件操作open、fopen与freopen http://blog.csdn.net/a656343072/article/details/40539889
- 实用的 AIX UNIX 命令
- IBM AIX 压缩