【BZOJ1563】诗人小G(决策单调性DP)

浪尽此生 提交于 2019-12-02 06:05:39

题意:给定N,L,P,求f[N]

 

 

 sum[i]递增,L<=3e6,P<=10

思路:四边形不等式的证明见https://www.byvoid.com/zhs/blog/noi-2009-poet

 

 

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 typedef pair<int,int> PII;
  8 typedef pair<ll,ll> Pll;
  9 typedef vector<int> VI;
 10 typedef vector<PII> VII;
 11 //typedef pair<ll,ll>P;
 12 #define N  300010
 13 #define M  200010
 14 #define INF 1e18
 15 #define fi first
 16 #define se second
 17 #define MP make_pair
 18 #define pb push_back
 19 #define pi acos(-1)
 20 #define mem(a,b) memset(a,b,sizeof(a))
 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 23 #define lowbit(x) x&(-x)
 24 #define Rand (rand()*(1<<16)+rand())
 25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 26 #define ls p<<1
 27 #define rs p<<1|1
 28 
 29 const //ll MOD=1e9+7,inv2=(MOD+1)/2;
 30       double eps=1e-6;
 31       //int INF=1e9;
 32       int dx[4]={-1,1,0,0};
 33       int dy[4]={0,0,-1,1};
 34 
 35 struct node
 36 {
 37     int l,r,id;
 38 }q[N];
 39 
 40 int n,L,P;
 41 ld dp[N],s[N];
 42 char ch[100];
 43 
 44 int read()
 45 {
 46    int v=0,f=1;
 47    char c=getchar();
 48    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 49    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 50    return v*f;
 51 }
 52 
 53 ld pw(ld x)
 54 {
 55     if(x<0) x=-x;
 56     ld ans=1;
 57     rep(i,1,P) ans*=x;
 58     return ans;
 59 }
 60 
 61 ld calc(int j,int i)
 62 {
 63     return dp[j]+pw(s[i]-s[j]-L+i-j-1);
 64 }
 65 
 66 void solve()
 67 {
 68     n=read(),L=read(),P=read();
 69     s[0]=0;
 70     rep(i,1,n)
 71     {
 72         scanf("%s",ch+1);
 73         int x=strlen(ch+1);
 74         s[i]=s[i-1]+x;
 75     }
 76     int h=0,t=0,l,r,last;
 77     q[0]={1,n,0};
 78     rep(i,1,n)
 79     {
 80         while(i>q[h].r) h++;
 81         dp[i]=calc(q[h].id,i);
 82         if(calc(i,n)>calc(q[t].id,n)) continue;
 83         while(i<q[t].l&&calc(i,q[t].l)<calc(q[t].id,q[t].l)) t--;
 84         l=max(q[t].l,i+1);
 85         r=q[t].r;
 86         last=min(n,q[t].r+1);
 87         while(l<=r)
 88         {
 89             int mid=(l+r)>>1;
 90             if(calc(i,mid)<calc(q[t].id,mid)){last=mid; r=mid-1;}
 91              else l=mid+1;
 92         }
 93         q[t].r=last-1;
 94         q[++t]={last,n,i};
 95     }
 96     if(dp[n]>INF) printf("Too hard to arrange\n");
 97      else printf("%lld\n",(ll)dp[n]);
 98     printf("--------------------\n");
 99 }
100 
101 int main()
102 {
103     int cas=read();
104     while(cas--) solve();
105     return 0;
106 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!