1563: [NOI2009]詩人小G
Time Limit: 100 Sec Memory Limit: 64 MB
Submit: 2611 Solved: 840Description
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。
htmlSource
【分析】ios
BZOJ1010玩具裝箱的增強版。這裏是^p不是平方。ide
這個是經典的1D/1D形式?【所謂1D/1D動態規劃,指的是狀態數爲O(n),每個狀態決策量爲O(n)的動態規劃方程。】測試
證實本身化式子啊。。spa
而後就是決策單調的意思,最優取值點不斷右移。code
這個爲何我以爲寫棧有點尷尬【要二分兩次?】,雙向鏈表就很好啊~~htm
st[i]表示i這個點的決策區間的起始位置,結束位置爲nt的起始的前一位或n。blog
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define LL long long 8 #define LD long double 9 #define Maxn 100010 10 const long double INF=1e18; 11 12 char s[50]; 13 LD a[Maxn],f[Maxn],len[Maxn],sm[Maxn],L; 14 int lt[Maxn],nt[Maxn],st[Maxn],P; 15 16 LD qpow(LD x,int b) 17 { 18 if(x<0) x=-x; 19 LD ans=1.0; 20 while(b) 21 { 22 if(b&1) ans*=x; 23 x*=x; 24 b>>=1; 25 } 26 return ans; 27 } 28 29 LD cal(int i,int j) 30 { 31 return f[j]+qpow(sm[i]-sm[j]+(LD)i-(LD)j-1.0-L,P); 32 } 33 34 bool check(int mid,int x,int y) 35 { 36 return cal(mid,x)>=cal(mid,y); 37 } 38 39 int n; 40 int ffind(int l,int r,int x,int y) 41 { 42 int ans=n+1; 43 while(l<=r) 44 { 45 int mid=(l+r)>>1; 46 if(check(mid,x,y)) ans=mid,r=mid-1; 47 else l=mid+1; 48 } 49 return ans; 50 } 51 52 int main() 53 { 54 int T; 55 scanf("%d",&T); 56 while(T--) 57 { 58 cin>>n>>L>>P;sm[0]=0; 59 for(int i=1;i<=n;i++) 60 { 61 scanf("%s",s);len[i]=(LD)strlen(s); 62 sm[i]=sm[i-1]+len[i]; 63 } 64 for(int i=0;i<=n;i++) f[i]=INF+1,st[i]=n+1,lt[i]=i-1,nt[i]=i+1; 65 f[0]=0;st[0]=1; 66 int now=0; 67 for(int i=1;i<=n;i++) 68 { 69 while(st[nt[now]]<=i) now=nt[now]; 70 f[i]=cal(i,now); 71 while(st[lt[i]]>i) 72 { 73 if(check(st[lt[i]],lt[i],i)) 74 { 75 lt[i]=lt[lt[i]]; 76 nt[lt[i]]=i; 77 } 78 else break; 79 } 80 st[i]=ffind(st[lt[i]],n,lt[i],i); 81 if(st[i]>n) nt[lt[i]]=nt[i],lt[nt[i]]=lt[i]; 82 } 83 if(f[n]>INF) printf("Too hard to arrange\n"); 84 else cout<<(LL)f[n]<<endl; 85 printf("--------------------\n"); 86 } 87 return 0; 88 }
2017-04-26 10:06:39ip