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 si<sj<sk should be held.
The rent cost is for the ci. Please determine the smallest cost Maria Stepanovna should pay.
The first line contains a single integer 3≤n≤3000) — the number of displays.
The second line contains 1≤si≤109) — the font sizes on the displays in the order they stand along the road.
The third line contains 1≤ci≤108) — the rent costs for each display.
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 si<sj<sk.
5
2 4 5 4 10
40 30 20 10 40
90
3
100 101 100
2 4 5
-1
10
1 2 3 4 5 6 7 8 9 10
10 13 11 14 15 12 13 13 18 13
33
In the first example you can, for example, choose displays 40+10+40=90.
In the second example you can't select a valid triple of indices, so the answer is -1.
题意: 给你n个数,每个数有两个权值(a,b),问取三个数,要求这三个数的a值递增,满足要求的最小三个数的和,没有满足要求的条件输出NO
暴力解法:
遍历中间一个数,然后两个循环分别找比他大的和比他小的,然后记录最小值
dp解法:
dp[i][j],i为第几个选择的数,j是选择的数的位置
这样的话,状态转移方程是:
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]);
暴力代码:
#include <map> #include <set> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <cstring> #include <iostream> #include <algorithm> #define debug(a) cout << #a << " " << a << endl using namespace std; const int maxn = 1e6 + 10; const int mod = 1e9 + 7; typedef long long ll; ll a[maxn], b[maxn]; int main(){ std::ios::sync_with_stdio(false); ll n; while( cin >> n ) { for( ll i = 0; i < n; i ++ ) { cin >> a[i]; } for( ll i = 0; i < n; i ++ ) { cin >> b[i]; } ll ans = 1e12; bool flag = false; for( ll i = 1; i < n; i ++ ) { ll min1 = 1e12, min2 = 1e12; for( ll j = i+1; j < n; j ++ ) { if( a[i] < a[j] ) { min1 = min( min1, b[j] ); } } for( ll j = 0; j < i; j ++ ) { if( a[i] > a[j] ) { min2 = min( min2, b[j] ); } } if( min1 != 1e12 && min2 != 1e12 ) { flag = true; ans = min( ans, min1 + min2 + b[i] ); } } if( flag ) { cout << ans << endl; } else { cout << -1 << endl; } } return 0; }
dp代码:
#include <map> #include <set> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <cstring> #include <iostream> #include <algorithm> #define debug(a) cout << #a << " " << a << endl using namespace std; const int maxn = 3*1e3 + 10; const int mod = 1e9 + 7; typedef long long ll; ll a[maxn], b[maxn], dp[maxn][maxn]; int main(){ std::ios::sync_with_stdio(false); ll n; while( cin >> n ) { for( ll i = 0; i < n; i ++ ) { cin >> a[i]; dp[2][i] = 1e12, dp[3][i] = 1e12; } for( ll i = 0; i < n; i ++ ) { cin >> b[i]; } ll ans = 1e12; for( ll j = 1; j < n; j ++ ) { for( ll i = 0; i < j; i ++ ) { if( a[i] < a[j] ) { dp[2][j] = min( dp[2][j] , b[i] + b[j] ); } } } for( ll j = 2; j < n; j ++ ) { for( ll i = 0; i < j; i ++ ) { if( a[i] < a[j] ) { dp[3][j] = min( dp[3][j], dp[2][i] + b[j] ); } } ans = min( ans, dp[3][j] ); } if( ans != 1e12 ) { cout << ans << endl; } else { cout << -1 << endl; } } return 0; }