zoukankan      html  css  js  c++  java
  • BZOJ 1563 诗人小G

    Description

    Input

    Output

    对于每组数据,若最小的不协调度不超过(10^{18}),则第一行一个数表示不协调度若最小的不协调度超过(10^{18}),则输出"(Too;hard;to;arrange)"(不包含引号)。每个输出后面加"(--------------------)"。

    Sample Input

    4
    4 9 3
    brysj,
    hhrhl.
    yqqlm,
    gsycl.
    4 9 2
    brysj,
    hhrhl.
    yqqlm,
    gsycl.
    1 1005 6
    poet
    1 1004 6
    poet

    Sample Output

    108
    (--------------------)
    32
    (--------------------)
    Too hard to arrange
    (--------------------)
    1000000000000000000
    (--------------------)

    【样例说明】
    前两组输入数据中每行的实际长度均为(6),后两组输入数据每行的实际长度均为(4)。一个排版方案中每行相邻两个句子之间的空格也算在这行的长度中(可参见样例中第二组数据)。每行末尾没有空格。

    Hint

    1D1D动态规划裸题。
    dp方程:$$f_{i}=min(f_{j}+(pre_{i}-pre_{j}+1)^{p})$$
    方便起见,我们在(pre_{i})上加个(1),于是dp方程变为$$f_{i}=min(f_{j}+(pre_{i}-pre_{j})^{p})$$
    这个方程很明显地满足单调性(令对于(f_{i})的转移(k)优于(j)(k > j)),则对于(v>i)(f_{v})的转移也有(k)优于(j))。
    斜率优化优化很明显当(p e 2)是行不通的。所以我们转向(O(nlogn))的1D1D的动态规划。
    1D1D动态规划是用二分单调栈来实现的。原理便是决策单调性,对于每个已经确定的(f_{i}),看其能更新的那一段后缀为那一段。在单调栈中进行二分,与之前的决策进行比较。不懂可以参考一下代码,代码应该好懂:

    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    #define limit (1e18)
    #define maxn 100010
    #define maxm 40
    int N,L,P,pre[maxn],top;
    char s[maxm];
    long double f[maxn];
    struct node { int l,r,key; }stack[maxn];
    
    inline long double qsm(int a,int b)
    {
    	long double  ret = 1;
    	while (b--) ret *= 1.0*a;
    	return ret;
    }
    
    inline long double calc(int a,int b)
    {
    	return f[b]+qsm(abs(pre[a]-pre[b]-L),P);
    }
    
    inline int find(int a)
    {
    	int l = 1,r = top,mid;
    	while (l <= r)
    	{
    		mid = (l + r) >> 1;
    		if (stack[mid].l<=a&&stack[mid].r>=a) return stack[mid].key;
    		if (a < stack[mid].l) r = mid - 1;
    		else l = mid + 1;
    	}
    }
    
    inline void updata(int now)
    {
    	int l = 1,r;
    	while (top)
    	{
    		if (calc(stack[top].l,stack[top].key) >= calc(stack[top].l,now))
    			--top;
    		else
    		{
    			l = stack[top].l,r = stack[top].r;
    			while (l <= r)
    			{
    				int mid = (l + r) >> 1;
    				if (calc(mid,stack[top].key) >= calc(mid,now)) r = mid - 1;
    				else l = mid + 1;
    			}
    			stack[top].r = r;
    			break;
    		}
    	}
    	if (l <= N) stack[++top] = (node){l,N,now};
    }
    
    inline void dp()
    {
    	f[0] = 0;
    	stack[top = 1] = (node) {1,N,0};
    	for (int i = 1;i <= N;++i)
    	{
    		int key = find(i);
    		f[i] = calc(i,key);
    		updata(i);
    	}
    }
    
    int main()
    {
    	freopen("1563.in","r",stdin);
    	freopen("1563.out","w",stdout);
    	int T; scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%d %d %d
    ",&N,&L,&P);
    		L++;
    		for (int i = 1;i <= N;++i)
    		{
    			scanf("%s",s);
    			pre[i] = strlen(s)+1+pre[i-1];			
    		}
    		dp();
    		if (f[N] > limit) printf("Too hard to arrange
    ");
    		else printf("%.0Lf
    ",f[N]);
    		printf("--------------------
    ");
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    CF 676C. Vasya and String 尺取经典题目
    进制转换
    《Dotnet9》系列-开源C# Winform控件库1《HZHControls》强力推荐
    《Dotnet9》系列-开源C# Winform控件库强力推荐
    《Dotnet9》系列-开源C# WPF控件库强力推荐
    《Dotnet9》系列-开源C# WPF控件库3《HandyControl》强力推荐
    《Dotnet9》系列-开源C# WPF控件库2《Panuon.UI.Silver》强力推荐
    《Dotnet9》系列之建站-Dotnet9建站20天感悟
    《Dotnet9》系列-开源C# WPF控件库1《MaterialDesignInXAML》强力推荐
    《Dotnet9》系列-FluentValidation在C# WPF中的应用
  • 原文地址:https://www.cnblogs.com/mmlz/p/4324338.html
Copyright © 2011-2022 走看看