ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

解题:NOI 2009 诗人小G

2019-03-01 19:40:46  阅读:223  来源: 互联网

标签:tmp NOI int double top 决策 三元组 解题 2009


题面

今天考试考了,于是开始糊学决策单调性DP

这是一个完全不会优化DP的人

决策单调性DP的一种优化方法是用单调队列优化

存下{左端点l,右端点r,最优决策点p}的三元组,按照单调队列的通常操作来说:

(0.初始化,将整个序列丢进去)

1.弹队头:弹掉所有不合法的三元组(r<i的)

2.求答案,同时更新队头的左端点

3.弹队尾:

①如果队尾的决策点不如i优,说明队尾这整个三元组当前的决策点太靠前了,直接弹掉

②当弹不掉时,根据决策单调性,队尾这个三元组后面的一部分决策点是i,前面的不是,二分出这个位置来修改。当然如果你发现事实上决策点在l就可以直接把整个都弹了=。=

4.入队(没啥可说的)

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define lli long long
 6 #define double long double
 7 using namespace std;
 8 const int N=100005;
 9 const lli inf=1e18;
10 struct a
11 {
12     int l,r,p;
13 }que[N];
14 int T,n,m,k,f,b,top,pre[N],stk[N]; 
15 lli len[N]; double dp[N]; char str[N][32];
16 double Qpow(double x,int k)
17 {
18     if(k==1) return x;
19     double tmp=Qpow(x,k/2);
20     return k%2?tmp*tmp*x:tmp*tmp;
21 }
22 double Calc(int a,int b)
23 {
24     return dp[b]+Qpow(fabs(len[a]-len[b]-m-1),k);
25 }
26 int main()
27 { 
28     scanf("%d",&T);
29     while(T--)
30     {
31         scanf("%d%d%d",&n,&m,&k);
32         for(int i=1;i<=n;i++)
33         {
34             scanf("%s",str[i]+1);
35             len[i]=len[i-1]+strlen(str[i]+1)+1;
36         }
37         que[f=b=0]=(a){1,n,0};
38         for(int i=1;i<=n;i++)
39         {
40             while(f<b&&que[f].r<i) f++;
41             int pt=que[f].p; que[f].l++;
42             dp[i]=Calc(i,pt),pre[i]=pt;
43             while(f<b&&Calc(que[b].l,que[b].p)>=Calc(que[b].l,i)) b--;
44             int lp=que[b].l,rp=que[b].r,ps=rp+1;
45             while(lp<=rp)
46             {
47                 int mid=(lp+rp)/2;
48                 if(Calc(mid,i)<=Calc(mid,que[b].p)) rp=mid-1,ps=mid;
49                 else lp=mid+1;
50             }
51             (ps==que[b].l)?b--:que[b].r=ps-1;
52             if(ps<=n) que[++b]=(a){ps,n,i};
53         }
54         if(dp[n]>inf) puts("Too hard to arrange");
55         else
56         {
57             printf("%lld\n",(lli)dp[n]),top=0;
58             for(int i=n;i;i=pre[i]) stk[++top]=i; stk[++top]=0; 
59             for(int i=top;i;i--)
60                 for(int j=stk[i+1]+1;j<=stk[i];j++)
61                 {
62                     printf("%s",str[j]+1);
63                     j==stk[i]?puts(""):putchar(' ');
64                 }
65         }
66         puts("--------------------");
67     }
68     return 0;
69 }
View Code

 

标签:tmp,NOI,int,double,top,决策,三元组,解题,2009
来源: https://www.cnblogs.com/ydnhaha/p/10458376.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有