HDU—1078 FatMouse and Cheese
Description
FatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension n: each grid location is labelled (p,q) where 0 <= p < n and 0 <= q < n. At each grid location Fatmouse has hid between 0 and 100 blocks of cheese in a hole. Now he's going to enjoy his favorite food.
FatMouse begins by standing at location (0,0). He eats up the cheese where he stands and then runs either horizontally or vertically to another location. The problem is that there is a super Cat named Top Killer sitting near his hole, so each time he can run at most k locations to get into the hole before being caught by Top Killer. What is worse -- after eating up the cheese at one location, FatMouse gets fatter. So in order to gain enough energy for his next run, he has to run to a location which have more blocks of cheese than those that were at the current hole.
Given n, k, and the number of blocks of cheese at each grid location, compute the maximum amount of cheese FatMouse can eat before being unable to move.
Input Specification
There are several test cases. Each test case consists of
- a line containing two integers between 1 and 100: n and k
- n lines, each with n numbers: the first line contains the number of blocks of cheese at locations (0,0) (0,1) ... (0,n-1); the next line contains the number of blocks of cheese at locations (1,0), (1,1), ... (1,n-1), and so on.
The input ends with a pair of -1's.
Output Specification
For each test case output in a line the single integer giving the number of blocks of cheese collected.
Sample Input
3 1
1 2 5
10 11 6
12 12 7
-1 -1
Output for Sample Input
37
【分析】
題意:老鼠從(0,0)開始每次可以往一個方向連續走[1,k]中任意的步數,但是每次要求所到達的位置的value要大於當前位置的value,求走到不能走為止,老鼠能吃到最大的value和
矩陣不大,直接考慮搜尋....搜尋很簡單,按題意搜就完事了
但是顯然複雜度超時了 粗略估計是O(4k^100)當然不可能真的這麼大,那麼顯然dfs做的大量操作都是重複的操作...每個點只需要遍歷一次找四個方向能去的4k個點之後能到達的最大value和就可以了
那麼考慮記憶化搜尋的話複雜度估計是O(100 * 4k)...每個點往上下左右四個方向各走k步
那也就沒啥了....直接爆搜就完了...每個點記錄下上下左右各k步返回的最大值加上當前value[x][y]記錄即可
當然既然可以記憶化搜尋,那麼dp也是可以的...dp就比較麻煩一點,需要對所有點進行處理,因為顯然要從value小的值開始搜尋....當然難也不是特別難,但是肯定沒有記憶化搜尋那麼容易理解了...
【程式碼】
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <deque>
#include <queue>
#include <algorithm>
#include <assert.h>
using namespace std;
#define clr(a,b) memset(a, b, sizeof(a))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define lson(x) (x << 1)
#define rson(x) (x << 1 | 1)
typedef long long LL;
typedef vector<LL> VI;
typedef pair<int,int> PII;
const LL mod=1000000007;
LL powmod(LL a,LL b) {LL res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
LL gcd(LL a,LL b) { return b?gcd(b,a%b):a;}
LL mod_inv(LL a, LL k) {return powmod(powmod(a, k), mod - 2) % mod;}
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
//std::ios::sync_with_stdio(false);
// head
int n,k;
int dirx[] = {0,-1,0,1};
int diry[] = {1,0,-1,0};
int vis[110][110];
int a[110][110];
int dfs(int x,int y){
if (vis[x][y]) return vis[x][y];
else{
int ans = 0 ;
for (int i = 1 ; i <= k ; ++i){
for (int j = 0 ; j < 4 ; ++j){
int xx = x + dirx[j] * i;
int yy = y + diry[j] * i;
if (a[xx][yy] <= a[x][y] || xx < 0 || xx >= n || yy < 0 || yy >= n) continue;
ans = max(ans , dfs(xx,yy));
}
}
return vis[x][y] = ans + a[x][y];
}
}
int main()
{
while (~scanf("%d%d",&n,&k) && n > 0 && k > 0 ){
memset(vis,0,sizeof(vis));
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < n ; ++j)
scanf("%d",&a[i][j]);
printf("%d\n", dfs(0,0));
}
return 0;
}