码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1563

时间:2015-04-08 21:13:20      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

 

对于很多决策单调性DP问题,我们很难(但不是不可以)证明其决策满足单调性,所以感觉很像时,可以打表看是否满足。

 

这道题的精度(?范围)很难搞,开始生怕溢出,看了hzwer的代码,才发现用long double,因为这道题只有乘法,没有除法,并且long double的保存系数的那部分还是挺大的(好像有效位数是64位)。

 

技术分享
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #define min(a,b) ((a)<(b)?(a):(b))
 5 #define max(a,b) ((a)>(b)?(a):(b))
 6 #define abs(a) ((a)<0?-(a):(a))
 7 #define mdp 1000000000000000000LL
 8 #define N 100010
 9 
10 typedef long double ddt;
11 
12 struct Trid {
13     int p, l, r;
14     Trid(){}
15     Trid( int p, int l, int r ):p(p),l(l),r(r){}
16 };
17 
18 int n, len, pw;
19 int w[N], sw[N], f[N]; 
20 ddt dp[N];
21 Trid stk[N]; int top;
22 
23 ddt pow( int a, int b ) {
24     ddt rt = 1;
25     for( int i=1; i<=b; i++ ) 
26         rt *= a;
27     return rt;
28 }
29 ddt getw( int j, int i ) {
30     return pow(abs(sw[i]-sw[j-1]+i-j-len), pw);
31 }
32 ddt calc( int j, int i ) {
33     ddt rt = dp[j-1]+getw(j,i);
34     if( rt<0 ) {
35         fprintf( stderr, "Overflow\n" );
36         exit(0);
37     }
38     return rt;
39 }
40 ddt dodp() {
41     stk[top=1] = Trid( 1, 1, n );
42     dp[1] = calc(1,1);
43     for( int i=2; i<=n; i++ ) {
44         if( calc(stk[top].p,n)>calc(i,n) ) {
45             while( stk[top].l>=i && calc(stk[top].p,stk[top].l)>calc(i,stk[top].l) )
46                 top--;
47             if( stk[top].r==i-1 ) {
48                 stk[++top] = Trid( i, i, n );
49             } else {
50                 int lf=max(stk[top].l+1,i);
51                 int rg=min(stk[top].r+1,n);
52                 while(lf<rg) {
53                     int mid=(lf+rg)>>1;
54                     if( calc(stk[top].p,mid)>calc(i,mid) )
55                         rg = mid;
56                     else
57                         lf = mid+1;
58                 }
59                 stk[top].r = lf-1;
60                 stk[++top] = Trid( i, lf, n );
61             }
62         }
63         int lf=1, rg=top;
64         while(lf<rg) {
65             int mid=(lf+rg+1)>>1;
66             if( stk[mid].l>i ) rg=mid-1;
67             else lf=mid;
68         }
69         dp[i] = calc(stk[lf].p,i);
70     }
71     return dp[n];
72 }
73 int main() {
74     int T;
75     scanf( "%d", &T );
76     while( T-- ) {
77         scanf( "%d%d%d", &n, &len, &pw );
78         for( int i=1; i<=n; i++ ) {
79             char buf[100];
80             scanf( "%s", buf );
81             w[i] = strlen(buf);
82             sw[i] = sw[i-1]+w[i];
83         }
84         ddt ans=dodp();
85         if( ans>mdp ) 
86             printf( "Too hard to arrange\n" );
87         else
88             printf( "%lld\n", (long long)ans );
89         printf( "--------------------\n" );
90     }
91 }
View Code

 

bzoj 1563

标签:

原文地址:http://www.cnblogs.com/idy002/p/4403503.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!