zoukankan      html  css  js  c++  java
  • hdu3507 Print Article DP+斜率优化

    点击打开链接

    题意:就是给一个序列,让你分成很多段,每段按照题目的公式算出答案,要所有的答案加起来最小


    思路一:(参考)http://www.cnblogs.com/lidaxin/p/5116577.html

    斜率优化。
    设f[i]表示前i个数分段后的最小值,则转移式为f[i]=min{f[j]+(sum[i]-sum[j])^2+M},1<=j<i
    进一步得:f[i]=min{ (f[j]+sum[j]^2-2*sum[i]*sum[j])+(sum[i]^2+M) }

    设y(j)=f[j]+sum[j]^2,a[i]=sum[i],x(j)=sum(j),则f[i]=min{y(j)-2*a[i]*x(j)}+sum[i]^2+M

    则要求min p=y+2ax , 单调队列维护下凸包。


    1 while(L<R && q[L+1].y-2*sum[i]*q[L+1].x <= q[L].y-2*sum[i]*q[L].x) L++;
    2 now.x = sum[i];
    3 now.y = q[L].y-2*sum[i]*q[L].x+2*sum[i]*sum[i]+m;
    4 while(L<R && cross(q[R-1],q[R],now)<=0) R--;
    5 q[++R] = now;
    now.y = y[i] = f[i]+sum[j]^2 = min{ (f[j]+sum[j]^2-2*sum[i]*sum[j])+(sum[i]^2+M) } + sum[i]^2

    答案就是  y[n]=q[R].y=f[n]+sum[n]^2  ==>  q[R].y-sum[n]^2; 

    代码一:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define mem(a) memset(a,0,sizeof(a))
     5 #define mp(x,y) make_pair(x,y)
     6 const int maxn = 5e5+10;
     7 const int INF = 0x3f3f3f3f;
     8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     9 inline ll read(){
    10     ll x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 //////////////////////////////////////////////////////////////////////////
    16 int n,m,a;
    17 int sum[maxn];
    18 
    19 struct node{
    20     int x,y;
    21 }now,q[maxn];
    22 
    23 int cross(node A,node B,node sum){
    24     return (B.x-A.x)*(sum.y-A.y) - (sum.x-A.x)*(B.y-A.y);
    25 }
    26 
    27 int main(){
    28     while(scanf("%d%d",&n,&m)==2){
    29         mem(sum);
    30         for(int i=1; i<=n; i++){
    31             scanf("%d",&a);
    32             sum[i] = sum[i-1]+a;
    33         }
    34 
    35         int L=0,R=0;
    36         for(int i=1; i<=n; i++){
    37             while(L<R && q[L+1].y-2*sum[i]*q[L+1].x <= q[L].y-2*sum[i]*q[L].x) L++;
    38             now.x = sum[i];
    39             now.y = q[L].y-2*sum[i]*q[L].x+2*sum[i]*sum[i]+m;
    40             while(L<R && cross(q[R-1],q[R],now)<=0) R--;
    41             q[++R] = now;
    42         }
    43 
    44         printf("%d
    ",q[R].y-sum[n]*sum[n]);
    45     }
    46 
    47     return 0;
    48 }


    思路二: 参考:http://www.cnblogs.com/kuangbin/archive/2012/08/26/2657650.html

    kuangbin大神= = 非常详细

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define mem(a) memset(a,0,sizeof(a))
     5 #define mp(x,y) make_pair(x,y)
     6 const int maxn = 5e5+10;
     7 const int INF = 0x3f3f3f3f;
     8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     9 inline ll read(){
    10     ll x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 //////////////////////////////////////////////////////////////////////////
    16 
    17 int n,m;
    18 int sum[maxn],f[maxn],q[maxn];
    19 
    20 // int slope(int j,int k){ // WA!!! 
    21 //     return ((double)(f[j]+sum[j]*sum[j]-(f[k]+sum[k]*sum[k]))) / ((double)(2*(sum[j]-sum[k])));
    22 // }
    23 
    24 int getUP(int j,int k)
    25 {
    26     return f[j]+sum[j]*sum[j]-(f[k]+sum[k]*sum[k]);
    27 }
    28 int getDOWN(int j,int  k)
    29 {
    30     return 2*(sum[j]-sum[k]);
    31 }
    32 
    33 int main(){
    34     //f[i]=min((sum[i]-sum[j])^2+m+f[j])
    35     while(scanf("%d%d",&n,&m)==2){
    36         sum[0],f[0]=0;q[0]=0;
    37         for(int i=1; i<=n; i++){
    38             int a; scanf("%d",&a);
    39             sum[i] = sum[i-1]+a;
    40         }
    41 
    42         int L=0,R=0;
    43         for(int i=1; i<=n; i++){
    44             while(L<R && getUP(q[L+1],q[L]) <= sum[i]*getDOWN(q[L+1],q[L])) 
    45                 L++;
    46             int j = q[L];
    47             f[i] = f[j] + (sum[i]-sum[j])*(sum[i]-sum[j]) + m;
    48             while(L<R && (getUP(i,q[R])*getDOWN(q[R],q[R-1]) <= getUP(q[R],q[R-1])*getDOWN(i,q[R]))) 
    49                 R--;
    50             q[++R] = i;
    51         }
    52 
    53         // int L=0,R=0;
    54         // for(int i=1; i<=n; i++){
    55         //     while(L<R && slope(q[L+1],q[L]) <= sum[i]) L++;
    56         //     int j = q[L];
    57         //     f[i] = f[j] + (sum[i]-sum[j])*(sum[i]-sum[j]) + m;
    58         //     while(L<R && slope(i,q[R]) <= slope(q[R],q[R-1])) R--;
    59         //     q[++R] = i;
    60         // }
    61         printf("%d
    ",f[n]);
    62     }
    63 
    64     return 0;
    65 }
  • 相关阅读:
    fastjson转换包含date类型属性的对象时报错com.alibaba.fastjson.JSONException: For input string: "13:02:19"
    HTTP Status 500
    org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
    myeclipse 报错:Set project compiler compliance settings to '1.5'
    Myeclipse安装svn插件
    junit单元测试报错Failed to load ApplicationContext,但是项目发布到tomcat浏览器访问没问题
    使用mybatis时,sql查出来的结果映射不进逆向工程生成的该模型
    整合mybatis时报错:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
    TinkerPop中的遍历:图的遍历步骤(3/3)
    TinkerPop中的遍历:图的遍历步骤(2/3)
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827710.html
Copyright © 2011-2022 走看看