POJ 3709 K-Anonymous Sequence 斜率DP
K-Anonymous Sequence POJ - 3709
给一个不降的序列,以及一个数 kkk,对这个序列进行操作,允许对某些数减去一定的值,要求操作之后的序列的每种取值的个数至少为 kkk,定义花费为修改前后每个数的绝对值的和,求最小花费。
令 dp[i]dp[i]dp[i] 表示前 iii 个数的最小花费,则转移方程为:
dp[i]=min{dp[j]+s[i]−s[j]−a[j+1]∗(i−j)} dp[i]=\min\{dp[j]+s[i]-s[j]-a[j+1]*(i-j)\} dp[i]=min{dp[j]+s[i]−s[j]−a[j+1]∗(i−j)}
其中 a[i]a[i]a[i] 为序列中第 iii 个元素的值,s[i]s[i]s[i] 为前缀和,这个式子的意思是前 iii 个数的最小花费为前 jjj 个数的最小花费加上第 j+1j+1j+1 个数到第 iii 个数都改成 a[j+1]a[j+1]a[j+1] 的花费。
考虑斜率DP,设 k<jk<jk<j ,且 jjj 优于 kkk,则有:
dp[j]+s[i]−s[j]−a[j+1]∗(i−j)<dp[k]+s[i]−s[k]−a[k+1]∗(i−k)(dp[j]−s[j]+ja[j+1])−(dp[k]−s[k]+ka[k+1])<i(a[j+1]−a[k+1])yj−ykxj−xk<i \begin{aligned} dp[j]+s[i]-s[j]-a[j+1]*(i-j)&<dp[k]+s[i]-s[k]-a[k+1]*(i-k)\\ (dp[j]-s[j]+ja[j+1])-(dp[k]-s[k]+ka[k+1])&<i(a[j+1]-a[k+1])\\ \frac{y_j-y_k}{x_j-x_k}&<i \end{aligned} dp[j]+s[i]−s[j]−a[j+1]∗(i−j)(dp[j]−s[j]+ja[j+1])−(dp[k]−s[k]+ka[k+1])xj−xkyj−yk<dp[k]+s[i]−s[k]−a[k+1]∗(i−k)<i(a[j+1]−a[k+1])<i
其中 yj=dp[j]−s[j]+ja[j+1],xj=a[j+1]y_j=dp[j]-s[j]+ja[j+1],x_j=a[j+1]yj=dp[j]−s[j]+ja[j+1],xj=a[j+1]。
代码如下(注意在队列尾进行判断的时候此处必须是 ≤\le≤):
#include<iostream> #include<cstdio> #include<cstring> //#define WINE #define INF 0x3f3f3f3f #define MAXN 500100 using namespace std; typedef long long ll; int n,k,T,q[MAXN],h,t; ll s[MAXN],dp[MAXN],a[MAXN]; ll up(int j,int k){ return dp[j]-s[j]+j*a[j+1]-(dp[k]-s[k]+k*a[k+1]); } ll down(int j,int k){ return a[j+1]-a[k+1]; } ll getDP(int k,int i){ return dp[k]+s[i]-s[k]-a[k+1]*(i-k); } int main(){ #ifdef WINE freopen("data.in","r",stdin); #endif scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); s[i]=s[i-1]+a[i]; } h=t=0;q[t++]=0; for(int i=k;i<=n;i++){ while(h+1<t&&up(q[h+1],q[h])<i*down(q[h+1],q[h])) h++; dp[i]=getDP(q[h],i); int j=i-k+1; if(j<k)continue; while(h+1<t&&up(j,q[t-1])*down(q[t-1],q[t-2])<=up(q[t-1],q[t-2])*down(j,q[t-1])) t--; q[t++]=j; } printf("%lld\n",dp[n]); } return 0; }
- 点赞
- 收藏
- 分享
- 文章举报
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- poj 3709 K-Anonymous Sequence 斜率优化dp
- POJ 3709 K-Anonymous Sequence (斜率优化DP)
- poj 3709 K-Anonymous Sequence dp斜率优化
- POJ 3709 K-Anonymous Sequence(斜率DP)
- poj 3709 K-Anonymous Sequence(DP-单调性优化-斜率优化)
- poj 3709 K-Anonymous Sequence 斜率优化dp 分组有大小限制
- POJ 3709 K-Anonymous Sequence(斜率优化DP)
- poj 3709 K-Anonymous Sequence 斜率优化dp
- poj 3709 K-Anonymous Sequence(斜率优化DP)
- POJ 3709 K-Anonymous Sequence 斜率优化
- POJ - 3709 K-Anonymous Sequence(斜率优化)
- poj 3709 K-Anonymous Sequence
- POJ 3709 K-Anonymous Sequence (单调队列优化)
- 【poj3709】K-Anonymous Sequence 【斜率优化dp】
- dp专辑 C - K-Anonymous Sequence [ 斜率优化]
- POJ 3709 K-Anonymous Sequence 笔记
- POJ 3709 K-Anonymous Sequence(单调队列)