Educational Codeforces Round 73 (Rated for Div. 2) D. Make The Fence Great Again ###K ###K //K

题目链接:https://codeforces.ml/contest/1221/problem/D
题意:求满足所有a[i]!=a[i-1]的最小花费 每个数可以+1 花费b[i]
思路:考虑每个数加或者不加的时候发现 没有办法用贪心来确定哪个数怎么加才是最优
那么只能考虑用dp来写,用dp来写的话每个数加的次数不能太多

所以要先想到每个数加的次数不会超过2 因为最多和相邻的两个数不同,所以最多像 4 4 5 这种加2次即可

然后dp[i][j] 代表 满足情况下的  第i个数加了j次的最小值  时间复杂度o(n*3*3)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pb push_back
 4 #define ll long long
 5 const int maxn=3e5+10;
 6 const int mod=1e9+7;
 7 int a[maxn],b[maxn];
 8 ll dp[maxn][3];
 9 
10 
11 int main()
12 {
13     ios::sync_with_stdio(0);
14     cin.tie(0);
15     int q;
16     cin>>q;
17     while(q--)
18     {
19         int n;
20         cin>>n;
21         for(int i=1;i<=n;i++)
22         {
23             cin>>a[i]>>b[i];
24         }
25         for(int i=1;i<=n;i++)
26             for(int j=0;j<3;j++)
27                 dp[i][j]=1e18;
28         dp[1][0]=0;
29         dp[1][1]=b[1];
30         dp[1][2]=2*b[1];
31         for(int i=2;i<=n;i++)
32         {
33             for(int j=0;j<3;j++)
34             {
35                 for(int x=0;x<3;x++)
36                 {
37                     if(a[i]+j==a[i-1]+x)
38                         continue;
39                     dp[i][j]=min(dp[i][j],dp[i-1][x]+j*b[i]);
40                 }
41             }
42         }
43         cout<<min({dp[n][0],dp[n][1],dp[n][2]})<<'\n';
44     }
45 
46 
47 
48 
49 
50 
51 }
View Code

 

posted @ 2020-11-11 16:49  canwinfor  阅读(78)  评论(0)    收藏  举报