D. Make The Fence Great Again
You have a fence consisting of nn vertical boards. The width of each board is 11. The height of the ii-th board is aiai. You think that the fence is great if there is no pair of adjacent boards having the same height. More formally, the fence is great if and only if for all indices from 22 to nn, the condition ai−1≠aiai−1≠ai holds.
Unfortunately, it is possible that now your fence is not great. But you can change it! You can increase the length of the ii-th board by 11, but you have to pay bibi rubles for it. The length of each board can be increased any number of times (possibly, zero).
Calculate the minimum number of rubles you have to spend to make the fence great again!
You have to answer qq independent queries.
The first line contains one integer qq (1≤q≤3⋅1051≤q≤3⋅105) — the number of queries.
The first line of each query contains one integers nn (1≤n≤3⋅1051≤n≤3⋅105) — the number of boards in the fence.
The following nn lines of each query contain the descriptions of the boards. The ii-th line contains two integers aiai and bibi (1≤ai,bi≤1091≤ai,bi≤109) — the length of the ii-th board and the price for increasing it by 11, respectively.
It is guaranteed that sum of all nn over all queries not exceed 3⋅1053⋅105.
It is guaranteed that answer to each query will not exceed 10181018.
For each query print one integer — the minimum number of rubles you have to spend to make the fence great.
3 3 2 4 2 1 3 5 3 2 3 2 10 2 6 4 1 7 3 3 2 6 1000000000 2
2 9 0
In the first query you have to increase the length of second board by 22. So your total costs if 2⋅b2=22⋅b2=2.
In the second query you have to increase the length of first board by 11 and the length of third board by 11. So your total costs if 1⋅b1+1⋅b3=91⋅b1+1⋅b3=9.
In the third query the fence is great initially, so you don't need to spend rubles.
這題。。。比賽的時候居然沒有做出來,嚶嚶嚶
1 /* 2 本題大意:給定一串數字,現在你要把這串數字變為相鄰數字不相等 3 的一串數字,變化方法為:對某個位置的數+1(可加無限多次),且有一定的花費,每個 4 位置花費不同,問最小花費。 5 本題思路: 6 本題可以說是想到就很好寫的線性dp了,因為不知道某個數字 7 到底要加幾次,也不知道某個數字加了之后會不會影響其它數字 8 ,我們不可能依次枚舉某個數字加的次數,但是我們很清晰的知道 9 每個數字最多只能加兩次,為什么呢?因為加入a[i] 和 a[i + 1] 10 相等,加入這次我們改變a[i],那么a[i] += 1;加了之后如果形成 11 了a[i - 1] == a[i],那么我們還可以選擇其中較小的花費加1,也 12 就是有可能選擇a[i]又加一,此時a[i] 肯定和兩端的數字都不一樣 13 所以說每個數字必定最多加兩次就可以使得他和左右兩邊的數字都不一樣。 14 也就是是說我們可以用記憶化搜索搞定這個題目。 15 我們用dp[i][j]表示第i個數字加了j次使得第i個數字之前的所有數字 16 不矛盾的最小花費,那么很明顯。 17 我們用j表示第i-1個數加的次數,k表示第i個數加的次數 18 因此我們判斷 19 if val[i] + k != val[i - 1] + j: 20 dp[i][k] = min(dp[i][k], dp[i - 1][j] + k * cost[i]) 21 */ 22 #include <cstdio> 23 #include <cstring> 24 using namespace std; 25 26 typedef long long ll; 27 const int maxn = 300000 + 5; 28 ll inf = 1e18 + 5; 29 int n; 30 ll a[maxn], b[maxn]; 31 ll dp[maxn][3]; 32 33 ll min(ll a, ll b) { 34 return a > b ? b : a; 35 } 36 37 int main() { 38 int q; 39 scanf("%d", &q); 40 while(q --) { 41 scanf("%d", &n); 42 for(int i = 0; i <= n; i ++) { 43 for(int j = 0; j < 3; j ++) dp[i][j] = inf; 44 } 45 for(int i = 1; i <= n; i ++) { 46 scanf("%lld %lld", a + i, b + i); 47 } 48 dp[0][0] = 0ll; 49 for(int i = 1; i <= n; i ++) { 50 for(int j = 0; j < 3; j ++) { 51 for(int k = 0; k < 3; k ++) { 52 if(a[i] + j != a[i - 1] + k) 53 dp[i][j] = min(dp[i][j], dp[i - 1][k] + j * b[i]); 54 } 55 } 56 } 57 printf("%lld\n", min(min(dp[n][0], dp[n][1]), dp[n][2])); 58 } 59 return 0; 60 }