您的位置:首页 > 其它

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

2015-06-18 12:38 369 查看
题目大意:玩具装箱,然而指数变成了pp(p≤10p\leq10)

首先我们需要证明决策单调

由于数死早,还是戳这里

知道决策单调之后怎么办呢?

由于是1D1D,所以不能分治了

每个决策点能决策的区间一定是连续的一段

并且随着决策点的右移 这个区间也在不断右移

令g[j]g[j]表示决策点jj能贡献的最左侧的位置

然后我们开一个栈来维护当前存在贡献的贡献点

那么显然stack[i]stack[i]的贡献区间是[g[stack[i]],g[stack[i+1]]−1][g[stack[i]],g[stack[i+1]]-1]

每新来一个点,首先在栈中二分找到最优决策点

然后将所有满足

f[stack[top]]+W(stack[top],g[stack[top]])>f[i]+W(i,g[stack[top]])f[stack[top]]+W(stack[top],g[stack[top]]) > f[i]+W(i,g[stack[top]])

的栈顶弹掉

然后二分找到最左侧的位置pospos满足

f[stack[top]]+W(stack[top],pos)>f[i]+W(i,pos)f[stack[top]]+W(stack[top],pos) > f[i]+W(i,pos)

那么这个pospos就是g[i]g[i],如果能找到这个pospos,就将ii压栈

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

[code]#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
-0.5>LIMIT)
            puts("Too hard to arrange");
        else
            cout<<(long long)(f
+0.5)<<endl;
        puts("--------------------");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: