【單調隊列優化dp】uestc 594 我要長高
阿新 • • 發佈:2017-08-29
() 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)單調隊列優化dp13 { 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 inthead=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 }
【坑】
第一種情況for循環要從1開始,而不是從x開始,雖然只有當j>=x時才能更新dp[cur][j],但q[head]有可能是dp[cur^1][j]在j<x時的值,換句話說j要考慮dp[cur^1]的所有可能值
另外,這道題用滾動數組節省了空間,因為每個韓子都只和他之前的一個有關,當然,第一個韓子要先處理好
【單調隊列優化dp】uestc 594 我要長高