题目链接:HDU5234
【题意】
很久很久以前,有一个叫Jack的枪手。他非常喜欢打猎。一天,他去了一个小树林。那儿有n只鸟,还有n棵树。第i只鸟站在第i棵树的顶端。这些树从左到右排成一条直线。每一棵树都有它的高度。Jack站在最左边那棵树的左边。当Jack在高度为H的地方向右发射一棵子弹时,站在高度为H的树上且离Jack最近的鸟儿就会落下来。
Jack会射击多次,他想知道每次射击哪只鸟儿会落下来。
【分析】很简单的DP题,dp[x][y][w][2]表示当前在点(x,y)获得了w重量并且当前点是否吃掉时获得的最大重量;我用记忆化写了。
【AC CODE】202ms
#include <cstdio> #include <cstring> #include <cctype> #include <cmath> #include <set> //#include <unordered_set> #include <queue> #include <stack> #include <vector> #include <string> #include <algorithm> using namespace std; typedef long long LL; #define rep(i,a,n) for(int i = a; i < n; i++) #define repe(i,a,n) for(int i = a; i <= n; i++) #define per(i,n,a) for(int i = n; i >= a; i--) #define clc(a,b) memset(a,b,sizeof(a)) const int INF = 0x3f3f3f3f, MAXN = 100+10; const int f[2][2]={{1,0},{0,1}}; int a[MAXN][MAXN], dp[MAXN][MAXN][MAXN][2],n,m,k; int dfs(int x, int y, int w, bool eat) { int &ans = dp[x][y][w][eat]; if(~ans) return ans; if(x == n-1 && y == m-1) { return 0; } ans = 0; rep(i,0,2) { int ni = x+f[i][0], nj = y+f[i][1]; if(0 <= ni && n > ni && 0 <= nj && m > nj) { int tmp = 0; if(w+a[ni][nj] <= k) tmp = dfs(ni,nj,w+a[ni][nj],1)+a[ni][nj]; if(tmp <= k) ans = max(tmp,ans); tmp = dfs(ni,nj,w,0); if(tmp <= k) ans = max(tmp,ans); } } return ans; } int main() { #ifdef SHY freopen("d:\\1.txt", "r", stdin); #endif while(~scanf("%d %d %d%*c", &n, &m, &k)) { clc(dp,-1); rep(i,0,n) { rep(j,0,m) scanf("%d%*c", &a[i][j]); } int ans = dfs(0,0,0,0); //clc(dp,-1); int tmp = 0; if(a[0][0] <= k) tmp = dfs(0,0,a[0][0],1)+a[0][0]; if(tmp <= k) ans = max(ans,tmp); printf("%d\n", ans); } return 0; }