uva 1632 Alibaba

题目大意:lrj306页 习题9-8 想了很久,区间DP的状态意识到了,但是不知道这个怎么和deadline联系起来,最后看别人的解题报告,恍然大悟,原来如此,顺便练了一下滚动数组,还是很有收获的。

题目链接:https://vjudge.net/problem/UVA-1632

第一份代码没有使用滚动数组,第二份使用了滚动数组,第二份比第一份的速度要上不少。


#include <cstdio>
#include <iostream>
#include <cstring>
#define min(a,b) (((a)<(b))?(a):(b))

using namespace std;

const int maxn = 10005 , inf = 0x3f3f3f3f;
int a[maxn] , d[maxn];
int dp[maxn][maxn][2];
int n;

void solve () {
    for (int i = 1 ; i <= n ; i++)
        dp[i][i][0] = dp[i][i][1] = 0;
    for (int i = n-1 ; i >= 1 ; i--) {
        for (int j = i+1 ; j <= n ; j++) {
            dp[i][j][0] = min(dp[i+1][j][0]+a[i+1]-a[i] , dp[i+1][j][1]+a[j]-a[i]);
            if (dp[i][j][0] >= d[i]) dp[i][j][0] = inf;
            dp[i][j][1] = min(dp[i][j-1][1]+a[j]-a[j-1] , dp[i][j-1][0]+a[j]-a[i]);
            if (dp[i][j][1] >= d[j]) dp[i][j][1] = inf;
        }
    }
    int ans = min(dp[1][n][0] , dp[1][n][1]);
    if (ans >= inf)
        cout << "No solution" << endl;
    else
        cout << ans << endl;
}

int main () {
    while (cin >> n) {
        memset (a,0,sizeof(a));
        memset (d,0,sizeof(d));
        memset (dp,0,sizeof(dp));
        for (int i = 1 ; i <= n ; i++)
            scanf("%d%d" , &a[i] , &d[i]);
        solve();
    }
}

#include <cstdio>
#include <iostream>
#include <cstring>
#define min(a,b) (((a)<(b))?(a):(b))

using namespace std;

const int maxn = 10005 , inf = 0x3f3f3f3f;
int a[maxn] , d[maxn];
int dp[2][maxn][2];
int n;

void solve () {
    dp[(n&1)^1][n][1] = dp[(n&1)^1][n][0] = 0;
    for (int i = n-1 ; i >= 1 ; i--) {
        int x = (i&1)^1;
        for (int j = i+1 ; j <= n ; j++) {
            dp[x][j][0] = min(dp[x^1][j][0]+a[i+1]-a[i] , dp[x^1][j][1]+a[j]-a[i]);
            if (dp[x][j][0] >= d[i]) dp[x][j][0] = inf;
            dp[x][j][1] = min(dp[x][j-1][1]+a[j]-a[j-1] , dp[x][j-1][0]+a[j]-a[i]);
            if (dp[x][j][1] >= d[j]) dp[x][j][1] = inf;
        }
    }
    int ans = min(dp[0][n][0] , dp[0][n][1]);
    if (ans >= inf)
        cout << "No solution" << endl;
    else
        cout << ans << endl;
}

int main () {
    while (cin >> n) {
        memset (a,0,sizeof(a));
        memset (d,0,sizeof(d));
        memset (dp,0,sizeof(dp));
        for (int i = 1 ; i <= n ; i++)
            scanf("%d%d" , &a[i] , &d[i]);
        solve();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值