zoukankan      html  css  js  c++  java
  • noi 2009 诗人小G 动态规划

    思路:设前i个句子和+i为sum[i]

    dp[i]表示以第i个为结尾的最小不协调度

    dp[i]=min(dp[j]+abs(sum[i]-sum[j]-l)^p);

    我们发现y=a1+abs(x-b1)^p和y=a2+abs(x-b2)^p至多有一个交点

    所以可以用斜率优化

    时间复杂度nlogMAXL

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 using namespace std;
      6 #define MAXN 110001
      7 #define MAXNL 3001000
      8 const double INF=1e18;
      9 const long long INF2=1000000000000000000LL;
     10 int n,l,T,p;
     11 double dp[MAXN];
     12 long long dp1[MAXN];
     13 char c[MAXN][31];
     14 int sum[MAXN],Q[MAXN],pre[MAXN],beh[MAXN];
     15 double poww(long double x,int y)
     16 {
     17     return pow(fabs(x),y);
     18 }
     19 long long my_pow(int x,int y)
     20 {
     21     if(x<0) x=-x;
     22     long long ans=1;
     23     for(int i=1;i<=y;i++)
     24     {
     25         ans=ans*x;
     26         if(ans>INF2)
     27             return INF2+1;
     28     }
     29     return ans;
     30 }
     31 int search(int x,int y)
     32 {
     33     int left=-MAXNL,right=MAXNL;
     34     while(left<right)
     35     {
     36         int mid=(left+right)/2;
     37         if(dp[x]+poww(mid-sum[x],p)<dp[y]+poww(mid-sum[y],p))
     38             left=mid;
     39         else
     40             right=mid;
     41         if(right-left==1)
     42             return left;
     43     }
     44 }
     45   
     46 bool check(int x,int y,int z)
     47 {
     48     int num=search(y,z);
     49     if(dp[x]+poww(num-sum[x],p)>=dp[y]+poww(num-sum[y],p))
     50         return 0;
     51     else return 1;
     52 }
     53   
     54 bool solve()
     55 {
     56     int i;
     57     int left,right;
     58     left=right=0;
     59     Q[0]=0; 
     60     for(i=1;i<=n;i++)
     61     {
     62  
     63         while(left<right&&dp[Q[left]]+poww(sum[i]-l-sum[Q[left]],p)>=dp[Q[left+1]]+poww(sum[i]-l-sum[Q[left+1]],p))
     64             left++;
     65         dp[i]=dp[Q[left]]+poww(sum[i]-l-sum[Q[left]],p);
     66         dp1[i]=dp1[Q[left]]+my_pow(sum[i]-l-sum[Q[left]],p);
     67         pre[i]=Q[left]+1;
     68         while(left<right&&check(Q[right-1],Q[right],i))
     69             right--;
     70         Q[++right]=i;
     71     }
     72     if(dp[n]>INF)
     73     {
     74         printf("Too hard to arrange\n");
     75         return 0;
     76     }
     77     printf("%lld\n",dp1[n]);
     78     return 1;
     79 }
     80 void output()
     81 {
     82     int i,j;
     83     for(i=n;i>0;i=pre[i]-1)
     84         beh[pre[i]]=i;
     85     for(i=1;i<=n;i=beh[i]+1)
     86     {
     87         for(j=i;j<beh[i];j++)
     88             printf("%s ",c[j]);
     89         printf("%s\n",c[j]);
     90     }
     91 }
     92   
     93 int main()
     94 {
     95     scanf("%d",&T);
     96     while(T--)
     97     {
     98         sum[0]=0;
     99         scanf("%d%d%d",&n,&l,&p);
    100         int i,j;
    101         for(i=1;i<=n;i++)
    102         {
    103             scanf("%s",c[i]);
    104             sum[i]=sum[i-1]+strlen(c[i])+1;
    105         };
    106         l++;
    107         dp1[0]=0;
    108         dp[0]=0;
    109         solve();
    110         output();
    111         printf("--------------------\n");
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    [Swift]LeetCode472. 连接词 | Concatenated Words
    [Swift]LeetCode470. 用 Rand7() 实现 Rand10() | Implement Rand10() Using Rand7()
    [Swift通天遁地]七、数据与安全-(19)使用Swift实现原生的SHA1加密
    [Swift通天遁地]七、数据与安全-(18)使用Swift实现原生的MD5加密
    [Swift通天遁地]七、数据与安全-(17)使用Swift实现原生的3DES加密和解密
    poj 1265 Area(pick 定理)
    Visual C++文件后缀名释义
    Linux 设备文件的创建和mdev
    37、ifconfig命令
    iOS开发- 生成/解析.vcf文件
  • 原文地址:https://www.cnblogs.com/myoi/p/2592759.html
Copyright © 2011-2022 走看看