zoukankan      html  css  js  c++  java
  • cqyz oj | 阿里巴巴

    Description

      在一条直线上有 n 件珠宝,已知每件珠宝的位置xi,并且第 i 件珠宝在 ti 时刻(单位:秒)就消失,问能否将所有的珠宝收集起来?如果能,求出最短时间。搜集能瞬间完成,但收集的人每秒只能移动一个单位的距离。

    Input

      若干组数据,每组数据的第一行为n,表示有n颗珠宝,接下来的n行,每行宝行两个整数:x,t,表示珠宝的位置和消失时间。

    Output

      如果有解,则输出一个整数,表示将所有珠宝收集完的最早完成时间,否则输出No solution。

    Sample Input 1 

    5
    1 3
    3 1
    5 8
    8 19
    10 15
    
    5
    1 5
    2 1
    3 4
    4 2
    5 3

    Sample Output 1

    11
    No solution

    Hint

    n<=10000
    0<=x,t<=10^9

    网上分析:

    f(i,j,0)表示区间i~j中获得所有宝藏并且停留在左端点,f(i,j,1)停留在右端点
    ans=min(f(1,n,0),f(1,n,1))
    i=j时,f(i,j,0)=f(i,j,1)=0;
    f(i,j,0)=min(f(i+1,j,1)+x[i+1]-x[i],f(i+1,j,0)+x[j]-x[i])
    f(i,j,1)=min(f(i,j-1,0)+x[j]-x[j-1],f(i,j-1,1)+x[j]-x[i])
    填表的时候需要按照主对角线填入

    加一个压行不然会爆空间

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 10005, inf = 0x3f3f3f3f;
    
    struct data{
        int x;
        int t;
        bool operator<(const data &b)const{
            return x < b.x;
        }
    }a[maxn];
    
    int n;
    bool data_in(){
        if(scanf("%d", &n) == 1){
            for(int i=1;i<=n;i++)
                scanf("%d%d", &a[i].x, &a[i].t);
            sort(a+1, a+1+n);
            return true;
        }
        else return false;
    }
    
    int f[2][maxn][2];
    /*
    f[i][j][0] = min(f[i+1][j][0]+x[i+1]-x[i], f[i+1][j][1]+x[j]-x[i])
    f[i][j][1] = min(f[i][j-1][0]+x[j]-x[i], f[i][j-1][1]+x[j]-x[j-1])
    */
    void solve(){
        memset(f, 0, sizeof(f));
        for(int len=2;len<=n;len++)
            for(int i=1;i+len-1<=n;i++){
                int j=i+len-1;
                f[i&1][j][0] = min(f[(i+1)&1][j][0]+a[i+1].x-a[i].x, f[(i+1)&1][j][1]+a[j].x-a[i].x);
                if(f[i&1][j][0] >= a[i].t) f[i&1][j][0] = inf;
                f[i&1][j][1] = min(f[i&1][j-1][0]+a[j].x-a[i].x, f[i&1][j-1][1]+a[j].x-a[j-1].x);
                if(f[i&1][j][1] >= a[j].t) f[i&1][j][1] = inf;
            }
        int ans = min(f[1][n][0], f[1][n][1]);
        if(ans<inf) printf("%d
    ", ans);
        else puts("No solution");
    }
    
    int main(){
        while(data_in())
            solve();
        return 0;
    }
    View Code
  • 相关阅读:
    ssh整合
    自定义Java集合
    java图形界面写个小桌面,内置简单小软件
    java简单日历
    javaSwing
    javaScript封装
    java解析xml文件
    缺省适配器
    适配器模式
    自定义SWT控件一之自定义单选下拉框
  • 原文地址:https://www.cnblogs.com/de-compass/p/11649805.html
Copyright © 2011-2022 走看看