Three displays (CodeForces - 987C )动态规划

题目链接:https://vjudge.net/problem/1602393/origin

------------------------------------------------------------------------------------------------------------------------------------------------------------

原题

Three displays

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和权值ci,让你从中选出3个值,使得i<j<k 且 

si<sj<sk,如果存在输出最小权值,不存在的话输出-1

题目思路:

         1. 先不去关注给予的权值序列C,单单看字体序列S,那么本题就是一道最长上升子序列

初始化 d[i] = 1(1<=i<=n);

最长上升子序列转移方程:   d[i] =  max( d[i] , d[j] + 1 | {i < j && si < sj } ); 时间复杂度O(n*n);

        2. 加入权值ci后 就变成   最长上升子序列+权值和最小 即可以假设在没有 序列C的情况下序列S的权值为1;

加入权值后,序列S的权值为ci ;

初始化  d[i] = ci;

转移方程:   d[i] = min(d[i] , d[j] + cj | {i < j && si < sj });时间复杂度O(n*n);

       3.再加入只取其中3个值的条件后  由于原有的以为数组状态无法保存2个状态;所以需要将数组改变为d[n][4];

表示下标为n是取一个值,取两个值,取三个值的状态。

初始化 d[i][1] = ci;

转移方程: d[i][2] = min (d[j][1] + d[i][1] | {i < j && si < sj});     d[i][3] = min (d[j][2] + d[i][1] | {i < j && si < sj});  

时间复杂度O(n*n);

       问题的解还需要遍历一遍d[i][3];

 废话不多说  ,上代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define INF 0xfffffffffffffff
using namespace std;
long long s[3005];
long long p[3005];
int n;
long long d[3005][4];
int main()
{	
	while (cin >> n){
		for (int i = 0; i < n; i++){
			cin >> s[i];
		}
		for (int i = 0; i < n; i++){
			cin >> p[i];
			d[i][1] = p[i];
			d[i][2] = d[i][3] = INF;
		}
		long long ans =INF;
		for (int i = 0; i < n; i++){
			for (int j = 0; j < i; j++){
				if (s[i] > s[j]){
					d[i][2] = min(d[i][1] + d[j][1], d[i][2]);
					d[i][3] = min(d[j][2] + d[i][1], d[i][3]);
				}
			}
			ans = min(ans, d[i][3]);
		}
		if (ans>=INF){
			printf("-1\n");
			continue;
		}
		cout <<ans<<endl;
	}
	return  0;
}




------------------------------------------------------------------------------------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/qq_39328456/article/details/80560242
今日推荐