洛谷P1912 [NOI2009]诗人小G(决策单调性)

传送门

题解

决策单调性是个啥……导函数是个啥……这题解讲的是啥……我是个啥……

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #define LD long double
 7 #define calc(i,j) f[j]+qpow(abs(s[i]-s[j]-L))
 8 using namespace std;
 9 inline int read(){
10     #define num ch-'0'
11     char ch;bool flag=0;int res;
12     while(!isdigit(ch=getchar()))
13     (ch=='-')&&(flag=true);
14     for(res=num;isdigit(ch=getchar());res=res*10+num);
15     (flag)&&(res=-res);
16     #undef num
17     return res;
18 }
19 const int N=1e5+5;
20 int n,L,P,s[N],q[N],k[N],pr[N];
21 LD f[N];char str[N][35];
22 inline LD qpow(LD x){
23     LD res=1;int k=P;
24     while(k){
25         if(k&1) res*=x;
26         k>>=1,x*=x;
27     }
28     return res;
29 }
30 inline int bound(int x,int y){
31     int l=x,r=n+1;
32     while(l<r){
33         int mid=l+r>>1;
34         calc(mid,x)>=calc(mid,y)?r=mid:l=mid+1;
35     }
36     return l;
37 }
38 int main(){
39     //freopen("testdata.in","r",stdin);
40     int T=read(),h,t;
41     while(T--){
42         n=read(),L=read()+1,P=read();
43         for(int i=1;i<=n;++i){
44             scanf("%s",str[i]);
45             s[i]=s[i-1]+strlen(str[i])+1;
46         }
47         q[h=t=1]=0;
48         for(int i=1;i<=n;++i){
49             while(h<t&&k[h]<=i) ++h;
50             f[i]=calc(i,q[h]),pr[i]=q[h];
51             while(h<t&&k[t-1]>=bound(q[t],i)) --t;
52             k[t]=bound(q[t],i),q[++t]=i;
53         }
54         if(f[n]>1e18) puts("Too hard to arrange");
55         else{
56             printf("%.0Lf\n",f[n]);
57             q[t=0]=n;int u=n;
58             while(u) q[++t]=u=pr[u];
59             for(;t;--t){
60                 int i;
61                 for(i=q[t]+1;i<q[t-1];++i) printf("%s ",str[i]);
62                 puts(str[i]);
63             } 
64         }
65         puts("--------------------");
66     }
67     return 0;
68 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9550944.html