1. 程式人生 > >【單調隊列優化dp】uestc 594 我要長高

【單調隊列優化dp】uestc 594 我要長高

() bsp using printf one blank bit style return

http://acm.uestc.edu.cn/#/problem/show/594

【AC】

技術分享
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=5e4+2;
 5 const int inf=0x3f3f3f3f;
 6 int n,c;
 7 int cur;
 8 int dp[2][maxn];
 9 int q[maxn];
10 int main()
11 {
12     while(scanf("%d%d",&n,&c)!=EOF)
13 { 14 int x; 15 scanf("%d",&x); 16 cur=0; 17 for(int i=1;i<x;i++) dp[cur][i]=inf; 18 for(int i=x;i<=100;i++) dp[cur][i]=(i-x)*(i-x); 19 for(int i=1;i<n;i++) 20 { 21 scanf("%d",&x); 22 cur^=1; 23 int
head=1,tail=0; 24 for(int j=1;j<=100;j++) 25 { 26 while(head<=tail&&q[tail]>=dp[cur^1][j]-c*j) tail--; 27 q[++tail]=dp[cur^1][j]-c*j; 28 if(j<x) dp[cur][j]=inf; 29 else dp[cur][j]=q[head]+j*c+(j-x)*(j-x);
30 } 31 head=1,tail=0; 32 for(int j=100;j>=x;j--) 33 { 34 while(head<=tail&&q[tail]>=dp[cur^1][j]+c*j) tail--; 35 q[++tail]=dp[cur^1][j]+c*j; 36 dp[cur][j]=min(dp[cur][j],q[head]-j*c+(j-x)*(j-x)); 37 } 38 } 39 int ans=inf; 40 for(int i=x;i<=100;i++) 41 { 42 ans=min(ans,dp[cur][i]); 43 } 44 printf("%d\n",ans); 45 } 46 return 0; 47 }
單調隊列優化dp

【坑】

第一種情況for循環要從1開始,而不是從x開始,雖然只有當j>=x時才能更新dp[cur][j],但q[head]有可能是dp[cur^1][j]在j<x時的值,換句話說j要考慮dp[cur^1]的所有可能值

另外,這道題用滾動數組節省了空間,因為每個韓子都只和他之前的一個有關,當然,第一個韓子要先處理好

【單調隊列優化dp】uestc 594 我要長高