题目链接http://codeforces.com/contest/987

C. Three displays
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 nn displays placed along a road, and the ii-th of them can display a text with font size sisi only. Maria Stepanovna wants to rent such three displays with indices i<j<ki<j<k that the font size increases if you move along the road in a particular direction. Namely, the condition si<sj<sksi<sj<sk should be held.

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

Input

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

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

The third line contains nn integers c1,c2,,cnc1,c2,…,cn (1ci1081≤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<ki<j<k such that si<sj<sksi<sj<sk.

Examples
input
Copy
5
2 4 5 4 10
40 30 20 10 40
output
Copy
90
input
Copy
3
100 101 100
2 4 5
output
Copy
-1
input
Copy
10
1 2 3 4 5 6 7 8 9 10
10 13 11 14 15 12 13 13 18 13
output
Copy
33
Note

In the first example you can, for example, choose displays 11, 44 and 55, because s1<s4<s5s1<s4<s5 (2<4<102<4<10), and the rent cost is 40+10+40=9040+10+40=90.

In the second example you can't select a valid triple of indices, so the answer is -1.

题意就是有三个物品,首先给每个位置的空间s[i],然后给出每个位置的的消耗,要求:是否存在三个位置,他们的顺序从小到大,他们的空间也从小到大,如果有找到这三个位置,找到这三个位置消耗和的最小值,如果没有就输出-1

怎么看怎么像DP但是不知道如何实现,后面经过大神指点。。。发现了这个二维DP。。。我只会n^3的复杂度.

想想为什么会超时。。。不就是三次方的问题嘛。。。能n^2解决就完美了。。。想想好像n^2的dp只能解决两个位置的情况。。。怎么办???既然确定是DP了,DP性质应该不会忘记把,子问题重叠。。。你没有发现吗?两个递增加一起不就是三个递增了吗?

转移方程。。。写了估计你也看不懂

DP[1][i]每个位置代表消耗

DP[2][j]这个位置与前面任意位置组合成的递增的两个的最小消耗

DP[3][i]这个位置与前面两个位置的组合成递增的三个的最小消耗

转移方程:     

dp[2][j]=min(dp[2][j],dp[1][i]+dp[1][j]);

dp[3][j]=min(dp[3][j],dp[2][i]+dp[1][j]);

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 using namespace std;
 5 const int maxx=0x3f3f3f3f;
 6 int main()
 7 {
 8     int n;
 9     int dp[4][3005];
10     int s[3005];
11     while (~scanf("%d",&n))
12     {
13         for(int i=1;i<=n; i++)
14         {
15             scanf("%d",&s[i]);
16         }
17         for (int i=1; i<=n; i++)
18         {
19             scanf("%d",&dp[1][i]);
20         }
21         for (int i=1;i<=n;i++){
22             dp[2][i]=maxx;//初始化最大
23         }
24         for(int j=2; j<=n; j++)
25         {
26             for(int i=1;i<j;i++)
27                 if(s[i]<s[j])
28                 {
29                       dp[2][j]=min(dp[2][j],dp[1][i]+dp[1][j]);
30                 }
31         }
32         int ans=maxx;
33         for (int j=3;j<=n;j++){
34             dp[3][j]=maxx;
35              for(int i=1;i<j;i++)
36                 if(s[i]<s[j])
37                 {
38                       dp[3][j]=min(dp[3][j],dp[2][i]+dp[1][j]);
39                 }
40             ans=min(ans,dp[3][j]);
41         }
42         if (ans!=maxx)
43         cout<<ans<<endl;
44         else cout<<"-1"<<endl;
45     }
46     return 0;
47 }