bzoj3628: [JLOI2014]天天酷跑
题目链接
题解
开始读错题目了,尴尬
由于题目说的跳跃次数和高度是在一开始设定的。
发现枚举一下记忆化搜索就可以过了
要注意,跳到最高点是可以不下坠继续连跳的
另外,上边界不能到达
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar(); }
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
const int maxn = 100007;
int n,m,c1,c2,h,freq;
#define INF 100000007
int a[23][maxn];
int f[23][maxn][6];
bool vis[23][maxn][6];
int dfs(int x,int y,int jumpcnt) {
if(y > n) return 0;
if(a[x][y] == -1) return -INF;
if(vis[x][y][jumpcnt]) return f[x][y][jumpcnt];
if(x == 1)jumpcnt = 0;
int tmp = -INF ;
if(jumpcnt < freq) {
int Sum = 0,tx = x,ty = y; bool can = true;
for(int i = 1;i < h;i ++) {
tx ++,ty ++;
if(a[tx][ty] == -1) {can = false; break; } Sum += a[tx][ty];
}
if(can) tmp = std::max(tmp,Sum + dfs(tx + 1,ty + 1,jumpcnt + 1));
}
if(x == 1) tmp = std::max(tmp, dfs(x,y + 1,0)) ;
if(x > 1) tmp = std::max(tmp, dfs(x - 1,y + 1,jumpcnt));
f[x][y][jumpcnt] = tmp + a[x][y];
vis[x][y][jumpcnt] = true;
return f[x][y][jumpcnt];
}
int ans = -INF ,an1,an2;
int main() {
n = read(),m = read(), c1 = read(),c2 = read();
for(int i = 1;i <= m;++ i) for(int j = 1;j <= n;++ j)
a[i][j] = read();
for(freq = 1;freq <= 5;++ freq)
for(h = 1;h * freq < m;++ h) {
memset(vis,0,sizeof vis);
memset(f,0,sizeof f);
int sum = dfs(1,0,m) - (h - 1) * c1 - (freq - 1) * c2;
if(sum > ans) ans = sum , an1 = h, an2 = freq;
}
if(ans > 0) printf("%d %d %d\n",ans,an2,an1);
else puts("mission failed");
return 0 ;
} #include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar(); }
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
const int maxn = 100007;
int n,m,c1,c2,h,freq;
#define INF 100000007
int a[23][maxn];
int f[23][maxn][6];
bool vis[23][maxn][6];
int dfs(int x,int y,int jumpcnt) {
if(y > n) return 0;
if(a[x][y] == -1) return -INF;
if(vis[x][y][jumpcnt]) return f[x][y][jumpcnt];
if(x == 1)jumpcnt = 0;
int tmp = -INF ;
if(jumpcnt < freq) {
int Sum = 0,tx = x,ty = y; bool can = true;
for(int i = 1;i < h;i ++) {
tx ++,ty ++;
if(a[tx][ty] == -1) {can = false; break; } Sum += a[tx][ty];
}
if(can) tmp = std::max(tmp,Sum + dfs(tx + 1,ty + 1,jumpcnt + 1));
}
if(x == 1) tmp = std::max(tmp, dfs(x,y + 1,0)) ;
if(x > 1) tmp = std::max(tmp, dfs(x - 1,y + 1,jumpcnt));
f[x][y][jumpcnt] = tmp + a[x][y];
vis[x][y][jumpcnt] = true;
return f[x][y][jumpcnt];
}
int ans = -INF ,an1,an2;
int main() {
n = read(),m = read(), c1 = read(),c2 = read();
for(int i = 1;i <= m;++ i) for(int j = 1;j <= n;++ j)
a[i][j] = read();
for(freq = 1;freq <= 5;++ freq)
for(h = 1;h * freq < m;++ h) {
memset(vis,0,sizeof vis);
memset(f,0,sizeof f);
int sum = dfs(1,0,m) - (h - 1) * c1 - (freq - 1) * c2;
if(sum > ans) ans = sum , an1 = h, an2 = freq;
}
if(ans > 0) printf("%d %d %d\n",ans,an2,an1);
else puts("mission failed");
return 0 ;
}