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 }

浙公网安备 33010602011771号