W
H
X

CF987C Three displays 题解

题目传送门

题目大意

n个位置,每个位置有两个属性s,c,要求选择3个位置i,j,k,使得s_i<s_j<s_k,并使得c_i+c_j+c_k最小

 

方法1

n³枚举每一种情况也许可以拿到部分分

这种做法最好往这交 (可以炸测评机

 

方法2

题目中要求一个有三个数的组合,不妨这样做:先算出两个数的组合,在转为三个数

假设现在正在考虑第 i 个数

从1到i-1枚举每一个数j

dp[i][2]表示以i结尾满足要求的两个数组合的最大的值,dp[i][3]表示以i结尾满足要求的三个数组合的最大的值

算出以i结尾的两个数组合

方法很简单 if (s[j] < s[i])  dp[i][2] = min(dp[i][2], c[i]+c[j]);

算出以i结尾的三个数组合

和算两个数差不多 if (s[j] < s[i])  dp[i][3] = min(dp[i][3], c[i]+dp[j][2]);

 

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <bits/stdc++.h>
using namespace std;
int n, s[3038], c[3038], f[3038][5], inf, ans;
int main(){
    memset (f, 0x7f/2, sizeof(f));
    ans = inf = f[1][1];
    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]);
    for (int i = 1; i <= n; i++)
      for (int j = 1; j < i; j++){
        if (s[j] >= s[i]) continue;
        f[i][2] = min (f[i][2], c[i] + c[j]);
        if (f[j][2] < inf)  f[i][3] = min (f[i][3], f[j][2] + c[i]);
        ans = min (ans, f[i][3]);
    }
    if (ans == inf) ans = -1;
    printf ("%d", ans);
    return 0;
} //不如点一下推荐吧~~~谢谢~~~

本文作者:-敲键盘的猫-

本文链接:https://www.cnblogs.com/whx666/p/10466192.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   -敲键盘的猫-  阅读(473)  评论(4编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起