Codeforces-987C - Three displays - 动态规划

题解链接

http://www.lucien.ink/archives/244/


题目链接

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


题目

It is the middle of 2018 and Maria Stepanovna, who lives outside Krasnokamensk (a town in Zabaikalsky region), wants to rent three displays to highlight an important problem.

There are n displays placed along a road, and the i-th of them can display a text with font size si only. Maria Stepanovna wants to rent such three displays with indices i < j < k that the font size increases if you move along the road in a particular direction. Namely, the condition si < sj < sk should be held.

The rent cost is for the i-th display is ci. Please determine the smallest cost Maria Stepanovna should pay.

Input

The first line contains a single integer n (3 ≤ n ≤ 3 000) — the number of displays.

The second line contains n integers s1 , s2 , … , sn (1 ≤ si ≤ 109 ) — the font sizes on the displays in the order they stand along the road.

The third line contains n integers c1 , c2 , … , cn (1 ≤ ci ≤ 108 ) — the rent costs for each display.

Output

If there are no three displays that satisfy the criteria, print -1. Otherwise print a single integer — the minimum total rent cost of three displays with indices i < j < k such that si < sj < sk.


题意

  给你一个长度为n的序列,每个序列有一个权值 si s i 和花费 ci c i ,让你从中选出3个值,使得 i<j<k i < j < k si<sj<sk s i < s j < s k ,如果存在输出最小话费,不存在的话输出-1


思路

  因为只用选出三个物品, f[i,k] f [ i , k ] 代表第 i i 个物品作为选出的三个物品中的第k个物品的最小花费,显然有: f[i,k]=min(f[j,k1]+c[i]) f [ i , k ] = m i n ( f [ j , k − 1 ] + c [ i ] ) ,其中: j<i j < i s[j]<s[i] s [ j ] < s [ i ]


实现

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3007, inf = 0x3f3f3f3f;
int f[maxn][4], n, val[maxn], cost[maxn], ans = inf;
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", val + i);
    for (int i = 1; i <= n; i++) scanf("%d", cost + i);
    memset(f, 0x3f, sizeof(f));
    for (int i = 1; i <= n; i++) {
        f[i][1] = cost[i];
        for (int k = 2; k <= 3; k++)
            for (int j = 1; j < i; j++)
                if (val[j] < val[i]) f[i][k] = std::min(f[i][k], f[j][k - 1] + cost[i]);
    }
    for (int i = 1; i <= n; i++) ans = std::min(ans, f[i][3]);
    printf("%d\n", ans == inf ? -1 : ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值