http://acm.hdu.edu.cn/showproblem.php?pid=2829
题意:
在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和.。然后给你m个炮弹,让你选择破坏掉m段铁路,使剩下的整条铁路的战略价值最小。
cost=∑i=lrVi(pre[r]−pre[i−1]−Vi)=∑i=lrVi(pre[r]−pre[i−1])−∑i=lrV2i
dp[i][j]表示到j为止的前面炸了i条路的得到最小总数
dp[i,j]=min(dp[i−1,k]+cost)=(pre[i]−pre[k])2−(pre2[i]−pre2[k])=
min(dp[i−1,k]+pre[i]2+pre[k]2−2∗pre[i]pre[k]−pre2[i]+pre2[k])
dp[i][j]=min(pre[i]2−pre2[i]−2pre[k]pre[i]+dp[i−1][k]+pre2[k]+pre[k]2)
代码中部分代码的解释
−2∗pr[k](k)
sq(pr[i])+pr2[i]+dp[i][−1](b)
pr[i](x)
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define mp make_pair
#define cl(a) memset((a),0,sizeof(a))
#ifdef HandsomeHow
#define dbg(x) cerr << #x << " = " << x << endl
#else
#define dbg(x)
#endif
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const int mod=1000000007;
const double pi=acos(-1.0);
inline void gn(long long&x){
int sg=1;char c;while(((c=getchar())<'0'||c>'9')&&c!='-');c=='-'?(sg=-1,x=0):(x=c-'0');
while((c=getchar())>='0'&&c<='9')x=x*10+c-'0';x*=sg;}
inline void gn(int&x){long long t;gn(t);x=t;}
inline void gn(unsigned long long&x){long long t;gn(t);x=t;}
ll gcd(ll a,ll b){return a? gcd(b%a,a):b;}
ll powmod(ll a,ll x,ll mod){ll t=1ll;while(x){if(x&1)t=t*a%mod;a=a*a%mod;x>>=1;}return t;}
// (づ°ω°)づe★------------------------------------------------
const int maxn = 1005;
ll dp[maxn][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 pr[maxn], pr2[maxn];
ll v[maxn];
int n,m;
int main(){
#ifdef HandsomeHow
freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
#endif
while(true){
gn(n);gn(m);
if(n==0&&m==0)break;
rep(i,1,n){
gn(v[i]);
pr[i]=pr[i-1]+v[i];
pr2[i]=pr2[i-1]+sq(v[i]);
}
dp[0][0]=0;
rep(i,1,n)dp[i][0]=sq(pr[i])-pr2[i];
rep(_,1,m){
hull.init();
hull.add(mp(0,0));
rep(i,1,n){
if(i <= _ + 1)
dp[i][_] = 0;
else
dp[i][_] = hull.ask(pr[i]) - pr2[i] + sq(pr[i]);
hull.add( mp( -2*pr[i],sq(pr[i]) + pr2[i] + dp[i][_-1] ) );
}
}
printf("%lld\n",dp[n][m]/2);
}
return 0;
}