[NOI2009]诗人小G 四边形优化DP
f[i] = min(f[j] + val(i,j);
其中val(i,j) 满足 四边形dp策略。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; char s[N][55]; int sum[N]; int ans[N]; long double f[N]; struct Node{ int j, l, r; }q[N]; int n, l, p; LL maxxx = 1e18; long double val(int i, int j){ if(i > j) swap(i,j); long double tt = abs(sum[j]-sum[i]+j-i-1-l); long double zz = 1; for(int i = 1; i <= p; ++i){ zz *= tt; } zz += f[i]; return zz; } void solve(int n){ if(n == 0) return ; solve(ans[n]); for(int i = ans[n]+1; i <= n; ++i){ printf("%s%c",s[i]," \n"[i==n]); } } int main(){ // cout << (702871197447575ll<1e18) << endl; int T; scanf("%d", &T); for(int _ = 1; _ <= T; ++_){ scanf("%d%d%d", &n, &l, &p); for(int i = 1; i <= n; ++i){ scanf("%s", s[i]); sum[i] = sum[i-1] + strlen(s[i]); } int L = 1, R = 1; q[L] = {0,1,n}; int midl; for(int i = 1; i <= n; ++i){ q[L].l = i; while(L <= R && q[L].r < i) ++L; ans[i] = q[L].j; f[i] = val(q[L].j,i); midl = n+1; while(L <= R && val(q[R].j, q[R].l) >= val(i, q[R].l)){ R--; } if(L <= R){ int ll = q[R].l, rr = q[R].r; while(ll <= rr){ int mid = (ll+rr) >> 1; if(val(q[R].j,mid) < val(i, mid)) ll = mid+1; else rr = mid - 1; } if(ll <= n){ q[R].r = ll-1; q[++R] = {i,ll,n}; } } else { q[++R] = {i,i+1,n}; } } if(f[n] > maxxx) puts("Too hard to arrange"); else{ LL fans = f[n]; printf("%lld\n", fans); solve(n); } puts("--------------------"); } return 0; }