1. 程式人生 > >1563: [NOI2009]詩人小G

1563: [NOI2009]詩人小G

div \n tps nbsp 一個點 sea fin () node

1563: [NOI2009]詩人小G

https://lydsy.com/JudgeOnline/problem.php?id=1563

分析:

  直接轉移f[i]=f[j]+cost(i,j),cost(i,j)=(sum[i]-sum[j])p

  然後有決策單調性,就可以二分+隊列了。

  證明?byvoid

  luogu輸出方案,加上後一直過不了,g,nxt數組是輸出方案的部分

代碼:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5
#include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #define fi(s) freopen(s,"r",stdin); 12 #define fo(s) freopen(s,"w",stdout); 13 using namespace std; 14 typedef long long LL; 15 typedef long
double LD; 16 17 inline int read() { 18 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==-)f=-1; 19 for(;isdigit(ch);ch=getchar())x=x*10+ch-0;return x*f; 20 } 21 22 const int N = 100005; 23 const LL INF = 1e18; 24 25 char str[N][32], pr[25]; 26 int len[N], g[N], nxt[N];
27 LD f[N]; 28 LL sum[N]; 29 int n, Len, P; 30 struct Node{ 31 int p, l, r; 32 Node() {} 33 Node(int _,int __,int ___) { p = _, l = __, r = ___; } 34 }q[N]; 35 36 LD ksm(LD x) { 37 LD ans = 1; int b = P; 38 while (b) { 39 if (b & 1) ans = ans * x; 40 x = x * x; 41 b >>= 1; 42 } 43 return ans; 44 } 45 void init() { 46 n = read(), Len = read(), P = read(); 47 for (int i=1; i<=n; ++i) { 48 scanf("%s", str[i] + 1); 49 sum[i] = sum[i - 1] + (len[i] = strlen(str[i] + 1) + 1); 50 } 51 } 52 LD Calc(int i,int j) { 53 return f[j] + ksm(abs(sum[i] - sum[j] - Len - 1)); 54 } 55 int binary_search(int l,int r,int x,int y) { 56 int ans = n; 57 while (l <= r) { 58 int mid = (l + r) >> 1; 59 if (Calc(mid, x) < Calc(mid, y)) ans = mid, r = mid - 1; 60 else l = mid + 1; 61 } 62 return ans; 63 } 64 void solve() { 65 int L = 1, R = 0; 66 q[++R] = Node(0, 1, n); 67 for (int i=1; i<=n; ++i) { 68 while (L <= R && q[L].r < i) L ++; 69 int j = q[L].p; 70 f[i] = Calc(i, j); 71 g[i] = j; 72 if (Calc(n, q[R].p) < Calc(n, i)) continue; // 如果最後一個點從i轉移不優,那麽說明i沒有覆蓋的區間,不需要二分了 73 while (L <= R && Calc(q[R].l, q[R].p) > Calc(q[R].l, i)) R --; 74 q[R].r = binary_search(q[R].l, n, i, q[R].p) - 1; 75 q[++R] = Node(i, q[R - 1].r + 1, n); 76 } 77 } 78 void print() { 79 if (f[n] > INF) puts("Too hard to arrange"); 80 else printf("%lld\n", (LL)(f[n])); 81 puts(pr); 82 } 83 int main() { 84 strcpy(pr, "--------------------"); 85 int T = read(); 86 while (T--) { 87 init(); 88 solve(); 89 print(); 90 } 91 return 0; 92 }

1563: [NOI2009]詩人小G