UVALive 6908 Electric Bike dp,BFS

来源:互联网 发布:大趋势炒股软件 编辑:程序博客网 时间:2024/05/29 07:11

题目链接:这里
题意:给了n段路,每段路长度不同,你有一辆车最多可以提供E的能量,你的车有四个档,最多换k次档
Assist Level 0 1 2 3
Assist Power 0 4 8 11
0档花费能量0,走的路程长度为0,1档花费1能量,走得最大路程为4…. ,每段路用一个档,如果这个档不能使你走完这段路,那么只能自己蹬,如果超过这段路长度,超过部分不计算到下一段路,意味着下一段路重算,问你蹬车的最短路程是多少?
解法:
最多1000段路,最多换10次档,最大提供能量为50,那么最多的状态为1000*10*50*4 =2e6,搜索所有状态的话2m也够,但是在搜索过程中肯定会挂掉很多状态,这些状态到中途夭折,所以能走到第n段路的状态肯定小于2e6,所以可以广搜,由此总结,可以用状态表示的都可以进行搜索枚举出来,只要状态少,在时间允许内,一般1e6,dp[i][k][e][l]=cost ,表示走到第i段路剩余k次机会,剩余e能量当前用的是l档的最短蹬车路程。

//UVAlive 6908#include <bits/stdc++.h>using namespace std;const int maxn = 1005;const int inf = 0x3f3f3f3f;int n, k, e;int a[maxn];int dp[maxn][11][55][4];bool vis[maxn][11][55][4];int power[4] = {0, 4, 8, 11};int ans;struct node{    int pos, k, e, l;    node(){}    node(int pos, int k, int e, int l) : pos(pos), k(k), e(e), l(l) {}};void bfs(){    queue <node> q;    memset(dp, inf, sizeof(dp));    memset(vis, 0, sizeof(vis));    dp[0][k][e][0] = 0;    vis[0][k][e][0] = 1;    q.push(node(0, k, e, 0));    while(!q.empty()){        node now = q.front(); q.pop();        int &nowdp = dp[now.pos][now.k][now.e][now.l];        if(now.pos == n){            ans = min(ans, nowdp);            continue;        }        if(now.k > 0){//还有换挡的机会&&换挡            for(int i  = 0; i < 4; i++){                if(i == now.l || now.e < i) continue;//可用能量小于花费肯定不行,不换挡的情况后面讨论                node nxt = now;                nxt.pos++; nxt.k--; nxt.e -= i; nxt.l = i;                int &nxtdp = dp[nxt.pos][nxt.k][nxt.e][nxt.l];                int cost = max(0, a[nxt.pos] - power[nxt.l]);                if(nxtdp > nowdp + cost){                    nxtdp = nowdp + cost;                    if(!vis[nxt.pos][nxt.k][nxt.e][nxt.l]){                        q.push(nxt);                        vis[nxt.pos][nxt.k][nxt.e][nxt.l] = 1;                    }                }            }        }        node nxt = now;        nxt.pos++;        if(nxt.e < nxt.l){//能量不够了,直接变成0 挡,不用花费,直接蹬            nxt.k = 0, nxt.e = 0, nxt.l = 0;        }        else{            nxt.k = now.k, nxt.l = now.l, nxt.e = now.e - now.l;        }        int cost = max(0, a[nxt.pos] - power[nxt.l]);        int &nxtdp = dp[nxt.pos][nxt.k][nxt.e][nxt.l];        if(nxtdp > nowdp + cost){            nxtdp = nowdp + cost;            if(!vis[nxt.pos][nxt.k][nxt.e][nxt.l]){                q.push(nxt);                vis[nxt.pos][nxt.k][nxt.e][nxt.l] = 1;            }        }    }}int main(){    int T, ks = 0;    scanf("%d", &T);    while(T--){        scanf("%d%d%d", &n, &k, &e);        for(int i = 1; i <= n; i++){            scanf("%d", &a[i]);        }        ans = inf;        bfs();        printf("Case #%d: %d\n", ++ks, ans);    }    return 0;}
0 0
原创粉丝点击