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
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。一个排版方案中每行相邻两个句子之间的空格也算在这行的长度中(可参见样例中第二组数据)。每行末尾没有空格。
--------------------
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 }