UVALive 6908 Electric Bike(dp)

题意:

N103K10E504
穿

分析:

dp
dp[i][k][e][l]:=100010504=2e6case=100T
spfa

代码:

//
//  Created by TaoSama on 2015-12-21
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e3 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, k, e, ans;
int h[N], f[N][11][51][4];
bool in[N][11][51][4];
int power[] = {0, 4, 8, 11};

struct Sta {
    int p, c, e, l; //position, chance, energy, level
};

void see(Sta u, Sta v) {
    int &cur = f[u.p][u.c][u.e][u.l];
    int &nxt = f[v.p][v.c][v.e][v.l];
    printf("f[%d][%d][%d][%d] = %d → ", u.p, u.c, u.e, u.l, cur);
    printf("f[%d][%d][%d][%d] = %d\n", v.p, v.c, v.e, v.l, nxt);
}

void spfa() {
    queue<Sta> q;
    memset(f, 0x3f, sizeof f);
    memset(in, false, sizeof in);
    f[0][k][e][0] = 0; in[0][k][e][0] = true;
    q.push((Sta) {0, k, e, 0});
    while(q.size()) {
        Sta u = q.front(); q.pop();
        in[u.p][u.c][u.e][u.l] = false;
        int &cur = f[u.p][u.c][u.e][u.l];
        if(u.p == n) {
            ans = min(ans, cur);
            continue;
        }
        if(u.c) {
            for(int i = 0; i < 4; ++i) {
                if(i == u.l || u.e < i) continue;
                Sta v = u;
                ++v.p; --v.c; v.e -= i; v.l = i;
                int cost = max(0, h[v.p] - power[v.l]);
                int &nxt = f[v.p][v.c][v.e][v.l];
                if(nxt > cur + cost) {
                    nxt = cur + cost;
//                  see(u, v);
                    if(!in[v.p][v.c][v.e][v.l]) {
                        in[v.p][v.c][v.e][v.l] = true;
                        q.push(v);
                    }
                }
            }
        }
        Sta v = u; ++v.p;
        if(v.e < v.l) v.c = v.e = v.l = 0; //lack energy, just set 0
        else v.e -= v.l;
        int cost = max(0, h[v.p] - power[v.l]);
        int &nxt = f[v.p][v.c][v.e][v.l];
        if(nxt > cur + cost) {
            nxt = cur + cost;
            if(!in[v.p][v.c][v.e][v.l]) {
                in[v.p][v.c][v.e][v.l] = true;
                q.push(v);
            }
        }
    }
}

int main() {
#ifdef LOCAL
    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    int t; scanf("%d", &t);
    while(t--) {
        scanf("%d%d%d", &n, &k, &e);
        for(int i = 1; i <= n; ++i) scanf("%d", h + i);

        ans = INF;
        spfa();
        static int kase = 0;
        printf("Case #%d: %d\n", ++kase, ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值