hdu 3507 斜率dp
2017-10-01 16:39
316 查看
传送门
设dp[i]表示输出前i个的最小费用,那么有如下的DP方程:
dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M } 0<j<i
其中 sum[i]表示数字的前i项和。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
const int maxn = 5e5+10;
ll dp[maxn];
typedef pair <ll, ll> Line;
#define k first
#define b second
struct ConvexHull
{
Line stk[maxn];
int l, r;
void init(){ l = r = 0; }
//sz r - l [l,r)
bool cover(Line &a, Line &b, Line &c)
{
// line a and b cover line c
return (a.k - b.k) * (b.b - c.b) >= (b.b - a.b) * (c.k - b.k);
// >= 下凸包 求最小值
// <= 上凸包 求最大值
}
void add(Line p)
{
while(r - l > 1 && cover(p,stk[r-2],stk[r-1]))r--;
stk[r++] = p;
}
ll calc(ll x, Line l){ return l.k * x + l.b; }
ll ask(ll x)
{
while(r - l > 1 && calc(x,stk[l+1]) <= calc(x,stk[l]))l++;
return calc(x,stk[l]);
}
}hull;
#undef k
#undef b
ll sq(ll x){ return x*x; }
ll v[maxn];
ll sum[maxn];
int n,m;
int T;
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
ll ans=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&v[i]);
sum[i]=sum[i-1]+v[i];
}
hull.init();
hull.add(mp(0,0));
for(int _=1;_<=n;_++)
{
dp[_]=sq(sum[_])+m+hull.ask(sum[_]);//常数
hull.add( mp(-2ll*sum[_],sq(sum[_])+dp[_]));//k b
}
printf("%lld\n",dp
);
}
}
设dp[i]表示输出前i个的最小费用,那么有如下的DP方程:
dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M } 0<j<i
其中 sum[i]表示数字的前i项和。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
const int maxn = 5e5+10;
ll dp[maxn];
typedef pair <ll, ll> Line;
#define k first
#define b second
struct ConvexHull
{
Line stk[maxn];
int l, r;
void init(){ l = r = 0; }
//sz r - l [l,r)
bool cover(Line &a, Line &b, Line &c)
{
// line a and b cover line c
return (a.k - b.k) * (b.b - c.b) >= (b.b - a.b) * (c.k - b.k);
// >= 下凸包 求最小值
// <= 上凸包 求最大值
}
void add(Line p)
{
while(r - l > 1 && cover(p,stk[r-2],stk[r-1]))r--;
stk[r++] = p;
}
ll calc(ll x, Line l){ return l.k * x + l.b; }
ll ask(ll x)
{
while(r - l > 1 && calc(x,stk[l+1]) <= calc(x,stk[l]))l++;
return calc(x,stk[l]);
}
}hull;
#undef k
#undef b
ll sq(ll x){ return x*x; }
ll v[maxn];
ll sum[maxn];
int n,m;
int T;
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
ll ans=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&v[i]);
sum[i]=sum[i-1]+v[i];
}
hull.init();
hull.add(mp(0,0));
for(int _=1;_<=n;_++)
{
dp[_]=sq(sum[_])+m+hull.ask(sum[_]);//常数
hull.add( mp(-2ll*sum[_],sq(sum[_])+dp[_]));//k b
}
printf("%lld\n",dp
);
}
}
相关文章推荐
- hdu 3507 斜率dp
- 【HDU 3507】Print Article(斜率优化DP)
- HDU 3507 Print Article【斜率优化dp】
- hdu 3507 斜率dp
- HDU 3507 Print Article [DP斜率优化]
- hdu 3507 斜率dp
- hdu 3507 Print Article(斜率优化DP)
- HDU - 3507 Print Article 斜率dp
- hdu 3507(DP+斜率优化)
- hdu 3507 斜率优化dp
- HDU 3507斜率优化dp
- hdu 3507 斜率dp
- HDU 3507 Print Article(斜率优化DP)
- hdu 3507 斜率优化dp入门
- HDU 3507:Print Article(斜率DP)
- hdu 3507 斜率dp
- hdu 3507 Print Article(斜率dp)
- HDU 3507 DP斜率优化 解题报告
- HDU 3507 Print Article 斜率优化DP
- HDU 3507 Print Article 斜率优化DP