2014-08-25 00:43:21
思路:本來想用遞推式寫的,寫了半天還是wa,原因在於方向,這題和以前hdu寫的走迷宮(只能右 / 下方向)湊最大點數那題不同,這題左右都可以走,而且又規定乙個格仔不能走兩遍,所以普通遞推dp是難以知道這個狀態是從哪個方向轉移來的,如果從右邊轉移來的,那麼接下來右邊就不能走了(左邊同理)。
所以為了方便,這題直接用記憶化搜尋解,dp[i][j][k][dir] 表示用[i,j]這個點到終點經過k次負權格仔,且狀態是從dir方向轉移來的最大路徑和。
(後來想想,如果在普通遞推dp中加上方向維度,可能也可行,呵呵)
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;
6const
int inf = 1
<< 30
;7 typedef long
long
ll;8
9int
n,k;
10int g[80][80
];11 ll dp[80][80][6][5
];12
int caled[80][80][6][5
];13
int vis[80][80
];14
int case = 0;15
16 ll dfs(int x,int y,int cnt,int
dir)23}
24if(x == 1 && y == 1)27
if(caled[x][y][cnt][dir])
30 caled[x][y][cnt][dir] = 1
;31 res = -inf;
32 vis[x][y] = 1;33
ll tem;
34if(y > 1 && !vis[x][y - 1
])38}39
if(y < n && !vis[x][y + 1
])43}44
if(x > 1 && !vis[x - 1
][y])48}
49 vis[x][y] = 0;50
//printf("dp[%d][%d][%d] : %d\n",x,y,cnt,res);
51return
res;52}
5354
intmain()61}
62 memset(vis,0,sizeof
(vis));
63 memset(caled,0,sizeof
(caled));
64 ll ans = dfs(n,n,0,1
);65 printf("
case %d:
",++case);
66if(ans == -inf)
69else72}
73return0;
74 }
uva 116 (記憶化搜尋)
題意 如圖,從左到右走,每次可以往左上 up 左 fo 左下 dn 走,當走到第一行或最後一行時可以如圖穿越。求一條權值最小的路徑,並列印字典序最小的路徑。解析 狀態轉移方程 dp i j min dp i 1 m m j 1 up dp i j 1 fo dp i 1 m j 1 dn 字典序最小...
uva10626(記憶化搜尋)
題目大意 一瓶可樂需要花8元,自動販售機只收1元,5元,10元。每次插入的錢只能買一瓶。給出n瓶可樂,請問最少插入幾次錢可以買到所需要數量的可樂。思路 一共有以下幾種情況 8個1元 插入8次 3個1元 乙個5元 插入4次 3個1元 乙個10元 插入4次 找5元 1個10元 插入1次 找2 1元 2個...
UVA 1629 記憶化搜尋
有乙個n行m列的蛋糕,切蛋糕,要求最後每一塊蛋糕上恰好有乙個櫻桃。問切割線總長度最小是多少?記憶化搜尋。設dp l r u d 為切割從橫向從l到r,縱向從u到d的一塊蛋糕,切割線總長度的最小值。然後不斷dfs搜尋並記錄dp值,最後dp 0 m n 0 即為所求。include include in...