Codeforces Round #485 (Div. 2)C. Three displays(动态规划DP)

版权声明:《学习技巧》每次使用单边大脑的时间不要太久,连续使用左边大脑30分钟就如同连续使用左臂30分钟一样,周期性的交换让大脑两侧能够轮流休息,左脑活动包括了循序渐进的工作,解决逻辑问题与分析,而右脑活动包括了隐喻,创造性思考,模式匹配和可视化。 https://blog.csdn.net/intmainhhh/article/details/82929216

题目传送门
题目大意:
给你一个长度为n的整数序列a[1…n].
以及一个长度为n的整数序列b[1…n].
现在,要求你选择三个正整数i,j,k(1<=i< j< k<=n).
使得a[i]< a[j]< a[k]且b[i]+b[j]+b[k]的值最小.
输出满足要求的b[i]+b[j]+b[k]的最小值。
Input
第一行一个整数n(3<=n<=3000),表示两个序列的长度.
第二行包含n个整数,第i个数字表示ai(1<=ai<=10^9).
第三行包含n个整数,第i个数字表示bi(1<=bi<=10^9).
Output
输出只有一个整数,表示b[i]+b[j]+b[k]的最小值.
如果找不到任何一个符合要求的i,j,k,则输出-1.
Examples
样例输入1
5
2 4 5 4 10
40 30 20 10 40
样例输出1
90
样例输入2
3
100 101 100
2 4 5
样例输出2
-1
样例输入3
10
1 2 3 4 5 6 7 8 9 10
10 13 11 14 15 12 13 13 18 13
样例输出3
33
题目分析
这是动态规划,主要用到了pair<int,int>v[maxn]存储两组数,dp[i][j]表示选到第i个结点选j个结点的最小花费,利用DP方程dp[i][j]=min(dp[i][j],dp[j][j-1]+v[i].second);求解。复杂度O(N^2)
代码如下

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=3000+10;
const long long INF = 0x7ffffffffffll;
pair<int,int>v[maxn];
long long dp[maxn][3];
int main() {
    int n;
    cin>>n;
    for(int i=0; i<n; i++) cin>>v[i].first;
    for(int i=0; i<n; i++) cin>>v[i].second;
    long long ans=INF;
    for(int i=0; i<n; i++) {
        dp[i][1]=v[i].second;
        dp[i][2]=dp[i][3]=INF;
        for(int j=0; j<i; j++)
            if(v[j].first<v[i].first) {
                dp[i][2]=min(dp[i][2],dp[j][1]+v[i].second);
                dp[i][3]=min(dp[i][3],dp[j][2]+v[i].second);
            }
        if(i>=2)
            ans=min(ans,dp[i][3]);
    }
    cout<<((ans==INF)?-1:ans)<<endl;
}

猜你喜欢

转载自blog.csdn.net/intmainhhh/article/details/82929216