CF C. Three displays(DP+思维)

http://codeforces.com/contest/987/problem/C

题意:给你两个n的序列要你根据第一个序列(严格单调递增的方式)在第二个序列里找3个数加起来,输出最小的一个。

思路:先从前往后枚举两个最小的。在从后往前找一个加上使其最小,最后遍历剩下的三元组。

AC代码:

#include<bits/stdc++.h>
#define ll long long

using namespace std;
const int maxn=4000;
const int INF=4*1e9;
struct node{
    int num,id;
};
struct node1{
    ll h,Sum;
};
node a[maxn];
node1 sum[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        sum[i].Sum=INF;
    }
    for(int i=1;i<=n;i++){
        cin>>a[i].id;
    }
    for(int i=1;i<=n;i++){
        cin>>a[i].num;
    }
    ll Min=4*1e9;
    for(int i=1;i<=n-1;i++){
              Min=4*1e9;
        for(int j=i+1;j<=n;j++){
            if(a[i].id<a[j].id){
                if(a[i].num+a[j].num<Min)
                {
                    Min=a[i].num+a[j].num;
                }
            }
        }
        sum[i].Sum=Min;
        sum[i].h=2;
    }
    //cout<<sum[2].Sum<<endl;

    for(int i=n-1;i>=2;i--){
             Min=4*1e9;
        for(int j=i-1;j>=1;j--){
            if(a[i].id>a[j].id){
                if(sum[i].Sum+a[j].num<Min){
                       Min=sum[i].Sum+a[j].num;
                }
            }
        }
        sum[i].Sum=Min;
        sum[i].h=3;
    }
    Min=4*1e9;
    int i,k;
    for( i=1;i<=n;i++){
        if(Min>sum[i].Sum&&sum[i].h==3){
            Min=sum[i].Sum;
            k=i;
        }
    }
    if(Min<INF){
    cout<<Min<<endl;
    }
    else
        cout<<"-1"<<endl;
    return 0;

}
View Code

大神:

#include <bits/stdc++.h>
using namespace std;
const int maxn=3010,inf=0x3f3f3f3f;
int s[maxn],c[maxn],f[maxn],dp[maxn];
int n,ans;
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&s[i]);
    for (int i=1;i<=n;i++) scanf("%d",&c[i]);
    dp[1]=inf;
    for (int i=2;i<=n;i++){
        dp[i]=inf;
        for (int j=i-1;j>=1;j--){
            if(s[i]>s[j])
                dp[i]=min(dp[i],c[i]+c[j]);
        }
//        printf("%d ",dp[i]);
    }
//    printf("
");
    ans=inf;
    for (int i=3;i<=n;i++){
        f[i]=inf;
        for (int j=i-1;j>=1;j--){
            if(s[j]<s[i]) f[i]=min(f[i],c[i]+dp[j]);
        }
//        printf("%d ",f[i]);
        ans=min(ans,f[i]);
    }
//    printf("
");
    if(ans==inf) puts("-1");
    else printf("%d
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/shuaihui520/p/9128123.html