POJ 1946 Cow Cycling (dp推荐)

那道题目看着好多状态。。。leader, speed, energy, distance,还有结果minute

可以看到:

1、某头牛变成leader以后的energy是 总能量 - distance。

2、当leader > N || energy < 0这些情况都是非法的。

3、distance == D这种情况是终止状态。

设 f[ld][sp][e][dis] 表示当前leader是ld,以速度sp到达能量剩余为e,行走距离为dis的状态所用的最少时间。

然后记忆化搜索可破

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <ctime>
#include <queue>
#include <map>
#include <sstream>

#define CL(arr, val)    memset(arr, (val), sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   ((l) + (r)) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)    (1 << (x))
#define iabs(x)  ((x) > 0 ? (x) : -(x))

typedef long long LL;
const double eps = 1e-12;
const int inf = ~0u>>2;

using namespace std;

int dp[21][11][110][110];
int N, D, E;

int solve(int l, int sp, int e, int dis) {
    if(l > N || e < 0)   return inf;
    if(dis == D)    return 0;

    if(dp[l][sp][e][dis] != -1) return dp[l][sp][e][dis];
    //printf("%d %d %d %d\n", l, sp, e, dis);

    int i, res = inf, n = sqrt(double(e));
    for(i = 1; i <= n; ++i) {
        res = min(res, solve(l, i, e - i*i, dis + i) + 1);
    }

    res = min(res, solve(l + 1, sp, E - dis, dis));
    dp[l][sp][e][dis] = res;
    return res;
}

int main() {
    //freopen("data.in", "r", stdin);
    //freopen("data.out", "w", stdout);

    while(~scanf("%d%d%d", &N, &E, &D)) {
        CL(dp,0XFF);
        int ans = solve(1, 0, E, 0);
        if(ans == inf)  puts("0");
        else    printf("%d\n", ans);
    }
    return 0;
}

 

 

 ps:看到状态多的情况要冷静,另外要敢写。写错了可以改,如果写都不敢写那就没有下一步了。。。

 

 

 

posted @ 2012-08-13 15:29  AC_Von  阅读(561)  评论(0编辑  收藏  举报