您的位置:首页 > 其它

Print Article [HDU 3507] 斜率优化DP模板

2013-04-27 12:43 411 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3507

View Code

const int MM = 555555;
#define debug puts("wrong")
#define mod 100000000
typedef __int64 int64;
int N,M;
int val[MM],sum[MM], dp[MM];
int head,tail,sq[MM];
/***************\
斜率优化DP  dp[i]=min(dp[j]+sqr(sum[i]-sum[j])+M | 1<=j<i)
对于队尾a b ,c插入 g[c,b]<=g[b,a] 则b对于最有策略没用
对于队首 b a,如有g[a,b]<=sum[i] 则a优于b,把b排除出队列
一开始压入0号构造的节点,防止边界条件,dp
为结果
对于斜率优化g[j,k]=(yj-yk)/(xj-xk)<const,则j优于k
\***************/
void get_data() {
int i,j,k;
sum[0]=0;
for(i=1;i<=N;i++) {
scanf("%d",&val[i]);
sum[i]=sum[i-1]+val[i];
}
}
int sqr(int x) {return x*x;}
int cal(int x,int y) { //x>y
return (dp[x]+sqr(sum[x]))-(dp[y]+sqr(sum[y]));
}
bool ok(int b,int a,int c) { //a>b
int tmp=cal(a,b);
int tt=(sum[a]-sum[b])<<1;
return tmp<=(sum[c]*tt);
}
bool ok1(int a,int b,int c) { //c>b>a
int t1,t2;
t1=cal(b,a)*((sum[c]-sum[b])<<1);
t2=cal(c,b)*((sum[b]-sum[a])<<1);
return t2<=t1;
}
void solve() {
int i,j,k,tt;
head=tail=dp[0]=0;
sq[tail++]=0;
for(i=1;i<=N;i++) {
while(head+1<tail && ok(sq[head],sq[head+1],i)) head++;
tt=sq[head];
dp[i]=dp[tt]+sqr(sum[i]-sum[tt])+M;

while(head+1<tail && ok1(sq[tail-2],sq[tail-1],i)) tail--;
sq[tail++]=i;
}
printf("%d\n",dp
);
}

int main() {
while(scanf("%d%d",&N,&M)!=EOF) get_data(),solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: