10201 - Adventures in Moving - Part IV

现在做动归还是没有什么思路,基本靠“蒙”,先假设状态,然后再去找状态转移方程,最后再修修补补。今天能做出这道题来感觉还是很兴奋的。

定义状态:f[i][j]表示在第i距离处车里还剩j升油所需的最小花费,如果能后到达终点,答案就是f[length][100];状态转移方程:f[i][j] = min(f[i][j], f[i-1][k] + (j - k) * m[i]);这里i-1表示i车站的前边的一个车站所在的位置,0<=k<j;还有f[i][j] = min(f[i][j], f[i - 1][j + w(i) - w(i - 1));复杂度为:O(100 * 200 *200);注意:有些车站可能在所要求的距离之外,这样的车站就不要了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <utility>
using namespace std;
#define x first
#define y second
const int INF = (1<<29);
typedef pair<int, int> pii;
pii p[110];
int f[10010][210];
char s[100];
int main()
{
    //freopen("input.txt", "r", stdin);
    int nCase;
    int leng, n, unsucc;
    scanf("%d", &nCase);
    while(nCase--){
        scanf("%d", &leng);
        getchar();
        n = 1;
        p[0].x = p[0].y = 0;
        unsucc = 0;
        while(gets(s)){
            if(strlen(s)){
                sscanf(s, "%d %d", &p[n].x, &p[n].y);
                if(n > 1){
                    if(p[n].x - p[n - 1].x > 200)
                        unsucc = 1;
                }else {
                    if(p[n].x > 100)
                        unsucc = 1;
                }
                if(p[n].x <= leng) n++;
            }else break;
        }
        if(leng - p[n - 1].x > 100) unsucc = 1;
        if(unsucc){
            printf("Impossible\n");
        }else{
            for(int i = 0; i <= leng; i++)
                for(int j = 0; j <= 200; j++)
                    f[i][j] = INF;
            f[0][100] = 0;
            int up;
            for(int i = 1; i < n; i++){
                for(int j = 0; j <= 200; j++){
                    if(j + p[i].x - p[i - 1].x <= 200)
                        f[p[i].x][j] = min(f[p[i].x][j], f[p[i - 1].x][j + p[i].x - p[i - 1].x]);
                    for(int k = 0; k < j; k++){
                        f[p[i].x][j] = min(f[p[i].x][j], f[p[i].x][k] + (j - k) * p[i].y);
                    }
                }
            }
            if(f[p[n - 1].x][100 + (leng - p[n - 1].x)] != INF)
                printf("%d\n", f[p[n - 1].x][100 + (leng - p[n - 1].x)]);
            else printf("Impossible\n");
        }
        if(nCase) printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值