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;
}




------------------------------------------------------------------------------------------------------------------------------------------------------------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章