HDU 3507 PrintArticle (单调队列优化)

题意:给出一个数列C,一个数字M,将数列分成若干段,每段的代价为(设这段的数字为k个):

dp[i]=min(dp[j]+(sum[i]-sum[j])*(sum[i]-sum[j])+M)

若j1<j2且j2比j1优

dp[j1]+sum[i]^2+sum[j1]^2-2*sum[i]*sum[j1]+M>dp[j2]+sum[i]^2+sum[j2]^2-2*sum[i]*sum[j2]

dp[j1]-dp[j2]+sum[j1]^2-sum[j2]^2>2*sum[i]*(sum[j1]-sum[j2])

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<string>
 6 #include<algorithm>
 7 int dp[500005],sum[500005],n,m,q[500005];
 8 int getup(int j,int k){
 9     return dp[j]+sum[j]*sum[j]-dp[k]-sum[k]*sum[k];
10 }
11 int getdown(int x,int y){
12     return 2*(sum[x]-sum[y]);
13 }
14 int getdp(int i,int j){
15     return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
16 }
17 int main(){
18     while (scanf("%d%d",&n,&m)==2){
19     for (int i=1;i<=n;i++){
20         scanf("%d",&sum[i]);
21     }
22     dp[0]=sum[0]=0;
23     for (int i=1;i<=n;i++)
24         sum[i]+=sum[i-1];
25     int h=0,t=0;
26     q[t++]=0;
27     for (int i=1;i<=n;i++){
28         while (h+1<t&&getup(q[h+1],q[h])<=sum[i]*getdown(q[h+1],q[h])) h++;
29         dp[i]=getdp(i,q[h]);
30         while (h+1<t&&getup(i,q[t-1])*getdown(q[t-1],q[t-2])<=getup(q[t-1],q[t-2])*getdown(i,q[t-1])) t--;
31         q[t++]=i;
32     }
33     printf("%d\n",dp[n]);}
34     return 0;
35 }
时间: 2024-10-10 11:32:04

HDU 3507 PrintArticle (单调队列优化)的相关文章

HDU 3401 Trade(单调队列优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:炒股.第i天买入一股的价钱api,卖出一股的价钱bpi,最多买入asi股,最多卖出bsi股.两次操作(买入或卖出)中间必须相差W天.炒股时间为n.任意时间手中的股票不大于MaxP.求最大收益. dp[i][j]代表第i天手上有j股的最大收益,dp[i][j]=max(dp[i-1][j],dp[i-W][k]+(j-k)*ap[i],dp[i-W][k]+(k-j)*bp[i]); dp

HDU 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch

HDU 3401 Trade dp 单调队列优化

戳这里:3401 题意:给出第 i 天的股票买卖价格(APi,BPi),以及每天股票买卖的数量上限(ASi,BSi),要求任两次交易需要间隔 W 天以上,即第 i 天交易,第 i + W + 1 天才能再交易,求最多能赚多少钱 思路:dp[i][j] = max(dp[i - 1][j], max(dp[f][k] - (j - k) * APi[i]), max(dp[f][k] + (k - j) * BPi[i])); 从式子中观察出,若两天都持有股票数 j 时,之后的那一天所赚的钱不小于

hdu 2191 (多重背包的单调队列优化)

多重背包单调队列优化是思想是.普通的dp为 dp[i][j]=max{dp[i-1][j-k*v[i]]+k*w[i]}; 其实你可以发现对能更新j是j和一个剩余类.也就是 0, v[i],2v[i],3v[i] ,4v[i]... 1 ,1+v[i],1+2v[i],1+3v[i] ........... v[i]-1,2*v[i]-1...... 更新值存在一个剩余类中,组与组之间不存在更新.那么实际上我们可以写dp写好这样 dp[b+x*v[i]]=max{ dp[b+k*v[i]]+(x

hdu3401 Trade(单调队列优化dp)

Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4734    Accepted Submission(s): 1587 Problem Description Recently, lxhgww is addicted to stock, he finds some regular patterns after a few d

Parade(单调队列优化dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 902    Accepted Submission(s): 396 Problem Description Panagola, The Lord of city F lik

HDU5945 Fxx and game 单调队列优化dp

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5945 题意: 求数x最少经过多少次变换能变为1,(1)如果x%k==0,那么可以x=x/k.(2)x=x-i,(1<=i<=t) 思路: 动规需要从1开始,一直往上计算,直到x为止. 递归公式为:dp[i]=min(min(dp[i-t]~dp[i-1])+1,dp[i/k]+1) min(dp[i-t]~dp[i-1])这个需要维护一个递增的单调队列优化,使得复杂度降为O(1). 只有当前满足

[Vijos 1243]生产产品(单调队列优化Dp)

Description 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器中的任何一台完成,但生产的步骤必须严格按顺序执行.由于这N台机器的性能不同,它们完成每一个步骤的所需时间也不同.机器i完成第j个步骤的时间为T[i,j].把半成品从一台机器上搬到另一台机器上也需要一定的时间K.同时,为了保证安全和产品的质量,每台机器最多只能连续完成产品的L个步骤.也就是说,如果有一台机器连续完

codevs3327选择数字(单调队列优化)

3327 选择数字 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入描述 Input Description 第一行两个整数n,k 以下n行,每行一个整数表示a[i]. 输出描述 Output Description 输出一个值表示答案. 样例输入 Sample Input 5 2