码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1563 NOI2009 诗人小G 四边形不等式

时间:2015-06-18 13:36:28      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj1563   noi2009   四边形不等式   决策单调   

题目大意:玩具装箱,然而指数变成了p(p10)

首先我们需要证明决策单调
由于数死早,还是戳这里

知道决策单调之后怎么办呢?
由于是1D1D,所以不能分治了

每个决策点能决策的区间一定是连续的一段
并且随着决策点的右移 这个区间也在不断右移

g[j]表示决策点j能贡献的最左侧的位置
然后我们开一个栈来维护当前存在贡献的贡献点
那么显然stack[i]的贡献区间是[g[stack[i]],g[stack[i+1]]?1]
每新来一个点,首先在栈中二分找到最优决策点
然后将所有满足
f[stack[top]]+W(stack[top],g[stack[top]])>f[i]+W(i,g[stack[top]])
的栈顶弹掉
然后二分找到最左侧的位置pos满足
f[stack[top]]+W(stack[top],pos)>f[i]+W(i,pos)
那么这个pos就是g[i],如果能找到这个pos,就将i压栈

由于数字可能过大因此要用long double代替long long进行计算

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
#define LIMIT 1000000000000000000ll
using namespace std;
typedef long double ld;
int n,l,p;
int sum[M],g[M],stack[M],top;
ld f[M];
long double Slow_Power(long double x,int y)
{
    long double re=1;
    for(int i=1;i<=y;i++)
        re*=x;
    return re;
}
int Get_Len()
{
    static char s[40];
    scanf("%s",s+1);
    return strlen(s+1);
}
int Get_Pos(int x)
{
    int l=1,r=top;
    while(r-l>1)
    {
        int mid=l+r>>1;
        if( g[stack[mid]]<=x )
            l=mid;
        else
            r=mid;
    }
    return g[stack[r]]<=x?r:l;
}
ld F(int j,int i)
{
    return f[j]+Slow_Power(fabs(sum[i]-sum[j]+(i-j-1)-l),p);
}
int Get_G(int x,int y)
{
    int l=max(g[x],y)+1,r=n+1;
    while(r-l>1)
    {
        int mid=l+r>>1;
        if( F(y,mid) < F(x,mid) )
            r=mid;
        else
            l=mid;
    }
    if(l==r) return r;
    return F(y,l) < F(x,l) ? l : r ;
}
int main()
{
    int T,i;
    for(cin>>T;T;T--)
    {
        cin>>n>>l>>p;
        for(i=1;i<=n;i++)
            sum[i]=sum[i-1]+Get_Len();
        g[0]=1;stack[top=1]=0;
        for(i=1;i<=n;i++)
        {
            int pos=stack[Get_Pos(i)];
            f[i]=F(pos,i);
            while( g[stack[top]]>i && F(i,g[stack[top]]) < F(stack[top],g[stack[top]]) )
                stack[top--]=0;
            pos=Get_G(stack[top],i);
            if(pos!=n+1)
            {
                stack[++top]=i;
                g[i]=pos;
            }
        }
        if(f[n]-0.5>LIMIT)
            puts("Too hard to arrange");
        else
            cout<<(long long)(f[n]+0.5)<<endl;
        puts("--------------------");
    }
    return 0;
}

BZOJ 1563 NOI2009 诗人小G 四边形不等式

标签:bzoj   bzoj1563   noi2009   四边形不等式   决策单调   

原文地址:http://blog.csdn.net/popoqqq/article/details/46546607

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!