BZOJ1563:[NOI2009]诗人小G(决策单调性DP)

Description

Input

Output

对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"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

总共10个测试点,数据范围满足:
测试点 T N L P
1 ≤10 ≤18 ≤100 ≤5
2 ≤10 ≤2000 ≤60000 ≤10
3 ≤10 ≤2000 ≤60000 ≤10
4 ≤5 ≤100000 ≤200 ≤10
5 ≤5 ≤100000 ≤200 ≤10
6 ≤5 ≤100000 ≤3000000 2
7 ≤5 ≤100000 ≤3000000 2
8 ≤5 ≤100000 ≤3000000 ≤10
9 ≤5 ≤100000 ≤3000000 ≤10
10 ≤5 ≤100000 ≤3000000 ≤10
所有测试点中均满足句子长度不超过30。

Solution 

题解

自闭了

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cmath>
 6 #define N (100009)
 7 #define LL long double
 8 #define MAX 1e18
 9 using namespace std;
10 
11 struct Node{int l,r,p;}q[N];
12 int T,n,l,p;
13 LL sum[N],f[N];
14 char s[N][35];
15 
16 LL Calc(int j,int i)
17 {
18     return f[j]+pow(abs(sum[i]-sum[j]+i-j-1-l),p);
19 }
20 
21 int Find(Node t,int x)
22 {
23     int l=t.l,r=t.r,ans=t.r+1;
24     while (l<=r)
25     {
26         int mid=(l+r)>>1;
27         if (Calc(x,mid)<=Calc(t.p,mid))
28             ans=mid,r=mid-1;
29         else l=mid+1;
30     }
31     return ans;
32 }
33 
34 void DP()
35 {
36     int head=1,tail=1;
37     q[1]=(Node){0,n,0};
38     for (int i=1; i<=n; ++i)
39     {
40         if (head<=tail && i>q[head].r) head++;
41         f[i]=Calc(q[head].p,i);
42         if (head>tail || Calc(i,n)<=Calc(q[tail].p,n))
43         {
44             while (head<=tail && Calc(i,q[tail].l)<=Calc(q[tail].p,q[tail].l)) tail--;
45             if (head>tail) q[++tail]=(Node){i,n,i};
46             else
47             {
48                 int now=Find(q[tail],i);
49                 q[tail].r=now-1;
50                 q[++tail]=(Node){now,n,i};
51             }
52         }
53     }
54 }
55 
56 int main()
57 {
58     scanf("%d",&T);
59     while (T--)
60     {
61         scanf("%d%d%d",&n,&l,&p);
62         for (int i=1; i<=n; ++i)
63             scanf("%s",s[i]);
64         for (int i=1; i<=n; ++i)
65             sum[i]=sum[i-1]+strlen(s[i]);
66         DP();
67         if (f[n]>MAX) puts("Too hard to arrange");
68         else printf("%lld\n",(long long)f[n]);
69         puts("--------------------");
70     }
71 }
posted @ 2018-10-08 14:44  Refun  阅读(180)  评论(0编辑  收藏  举报