2019.03.13 ZJOI2019模拟赛 解题报告

得分: \(55+12+10=77\)(\(T1\)误认为有可二分性,\(T2\)不小心把\(n\)开了\(char\),\(T3\)直接\(puts("0")\)水\(10\)分)

\(T1\):Bug 级的存在

感觉只有我这种智障才会觉得这题有可二分性。

显然,若要一段区间能够成为公差为\(d\)的等差序列,则一个基本要求就是这段区间要模\(d\)同余

因此,我们首先自然就是把每段同余的区间单独抠出来处理。

然后我们把这段区间内的数同整除\(d\)。

但要注意,正数和负数同整除\(d\)可能会出问题,例如\(d=3\)时\(\lfloor\frac{-2}3\rfloor=\lfloor\frac13\rfloor=0\),而且负数在前面的取余操作中也略显麻烦。

因此,我们需要将每个数都减去这个序列中的最小值,这样就可以把每个数都变成非负整数了。

同整除\(d\)之后,对于一个符合条件的区间\([l,r]\),我们应满足其加上至多\(k\)个数后成为一个连续的序列

即我们需要满足:\(max_{i=l}^ra_i-min_{i=l}^ra_i+1\le(r-l+1)+k\),且不存在相同的\(a_i\)。

之所以要满足这个不等式,因为不等式左半边表示若要使这段区间成为一个连续的序列至少需要的数的总数,右半边\(r-l+1\)表示这段区间内原有的数的个数,\(k\)表示至多可以加数的个数,显然需要数的总数应小于等于原有的数的个数与可以加数的个数。

然后考虑移项,可以化简得到:

\[max_{i=l}^ra_i-min_{i=l}^ra_i+l\le r+k\]

则不难发现,在确定\(r\),即确定右端点的情况下,我们显然就是要找到一个最小的\(l\),即左端点满足上述式子。

考虑到在我们从左往右枚举右端点的过程中,可以顺带开两个单调栈来维护\(min\)和\(max\),并考虑用线段树来维护每个点到当前\(r\)的\(max-min+l\)(\(l\)即为每个点的编号)。

最后直接在线段树上查询权值\(\le r+k\)的编号最小的点即可。

但要注意更新在线段树上查找时的下界,即前面提到过的附加条件不存在相同的\(a_i\)

我们可以开一个\(map\)叫做\(lst\)来记录每个点上次出现的位置,记住每次将询问下界与\(lst[a_i]+1\)取\(min\),然后更新\(lst[a_i]=i\),就可保证不存在相同的\(a_i\)了。

最后,还有一个需要特判的地方,即\(d=0\),这样前面的取模与整除等运算会全部\(RE\)。

因此,我们要特判\(d=0\),而此时也很容易,只要\(O(n)\)扫一遍找出最长的一段元素全相同的区间即可。

代码如下:

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define CL Con LL&
#define I inline
#define W while
#define N 200000
#define min(x,y) ((x)<(y)?(x):(y))
#define Gmax(x,y) (x<(y)&&(x=(y)))
#define Gmin(x,y) (x>(y)&&(x=(y)))
#define LL long long
#define INF 1e9
using namespace std;
int n,k,d,a[N+5],Mod[N+5];
class FastIO
{
    private:
        #define FS 100000
        #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
        #define tn (x<<3)+(x<<1)
        #define D isdigit(c=tc())
        int f;char c,*A,*B,FI[FS];
    public:
        I FastIO() {A=B=FI;}
        Tp I void read(Ty& x) {x=0,f=1;W(!D) f=c^'-'?1:-1;W(x=tn+(c&15),D);x*=f;}
        Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
        #undef D
}F;
class DEqualsToZeroSolver//特判d=0的情况
{
    public:
        I void Solve()
        {
            RI i,t=1,ansl=0,ansr=0;
            for(i=2;i<=n;++i) a[i]^a[i-1]&&((i-t>ansr-ansl+1)&&(ansl=t,ansr=i-1),t=i);//扫一遍求最长的一段元素全相同的区间
            printf("%d %d",ansl,ansr);//输出答案
        }
}Zero;
class SegmentTreeSolver//利用线段树维护信息求解答案
{
    private:
        int ansl,ansr,s[N+5],S1[N+5],S2[N+5];map<int,int> lst;
        class SegmentTree//线段树
        {
            private:
                #define STO l,hl,rt<<1
                #define ORZ hl+1,r,rt<<1|1
                #define PU(x) (O[x]=O[x<<1]+O[x<<1|1])
                #define PD(x) (O[x].f&&(O[x<<1]+=O[x].f,O[x<<1|1]+=O[x].f,O[x].f=0))
                int n;
                struct Interval//存储区间信息
                {
                    LL Mn,f;I Interval(CL m=0,CL p=0):Mn(m),f(p){}
                    I Interval operator + (Con Interval& t) Con {return Interval(min(Mn,t.Mn));}
                    I void operator += (CL x) {Mn+=x,f+=x;}
                }O[N<<3];
                I void upt(CI l,CI r,CI rt,CI ul,CI ur,CI v)//区间修改
                {
                    if(ul<=l&&r<=ur) return O[rt]+=v;PD(rt);RI hl=l+r>>1;
                    ul<=hl&&(upt(STO,ul,ur,v),0),ur>hl&&(upt(ORZ,ul,ur,v),0),PU(rt);
                }
                I int ask(CI l,CI r,CI rt,CI v)//查询权值小于等于v的最左端点
                {
                    if(O[rt].Mn>v) return INF;if(PD(rt),!(l^r)) return l;
                    RI hl=l+r>>1;return O[rt<<1].Mn<=v?ask(STO,v):ask(ORZ,v);
                }
                I int qry(CI l,CI r,CI rt,CI ql,CI qr,CI v)//查询给定区间内权值小于等于v的最左端点(先找到区间,然后调用ask函数)
                {
                    if(PD(rt),ql<=l&&r<=qr) return ask(l,r,rt,v);RI hl=l+r>>1,res=INF,t;
                    return ql<=hl&&(t=qry(STO,ql,qr,v),Gmin(res,t)),qr>hl&&(t=qry(ORZ,ql,qr,v),Gmin(res,t)),res;
                }
                I void Build(CI l,CI r,CI rt)//建树,即清空线段树
                {
                    if(!(l^r)) return (void)(O[rt]=Interval(),0);RI hl=l+r>>1;
                    Build(STO),Build(ORZ),PU(rt);
                }
            public:
                I void Init(CI x) {n=x,Build(1,n,1);}I void Update(CI l,CI r,CI v) {upt(1,n,1,l,r,v);}
                I int Query(CI l,CI r,CI v) {RI t=qry(1,n,1,l,r,v);return min(t,r);}
        }T;
    public:
        I SegmentTreeSolver() {ansl=ansr=1;}
        I void Solve(CI l,CI r)
        {
            RI i,t,cnt=0,T1=0,T2=0,L=1;for(i=l;i<=r;++i) s[++cnt]=a[i]/d;//把区间内所有数整除d的结果存储下来
            for(T.Init(cnt),lst.clear(),i=1;i<=cnt;++i)//清空线段树和map,然后枚举右端点i
            {
                W(T1&&s[S1[T1]]<=s[i]) T.Update(S1[T1-1]+1,S1[T1],s[i]-s[S1[T1]]),--T1;//单调栈维护最小值,同时在线段树上修改-min
                W(T2&&s[S2[T2]]>=s[i]) T.Update(S2[T2-1]+1,S2[T2],s[S2[T2]]-s[i]),--T2;//单调栈维护最小值,同时在线段树上修改max
                Gmax(L,lst[s[i]]+1),lst[s[i]]=S1[++T1]=S2[++T2]=i,T.Update(i,i,i),//更新询问下界,将i加入栈,并在线段树中i这一位上增加i(因为i之后会被作为左端点,因此要将它加上自身编号)
                t=T.Query(L,i,i+k),i-t>ansr-ansl&&(ansl=l+t-1,ansr=l+i-1);//询问最小的满足要求左端点,然后更新答案
            }
        }
        I void PrintAns() {printf("%d %d",ansl,ansr);}//输出答案
}S;
int main()
{
    freopen("bug.in","r",stdin),freopen("bug.out","w",stdout);
    RI i,t=INF;for(F.read(n,k,d),i=1;i<=n;++i) F.read(a[i]);if(!d) return Zero.Solve(),0;//读入数据,特判d=0的情况
    for(i=1;i<=n;++i) Gmin(t,a[i]);for(i=1;i<=n;++i) Mod[i]=(a[i]-=t)%d;Mod[n+1]=-1;//将所有数化为非负整数,然后存下模d的余数
    for(t=1,i=2;i<=n+1;++i) Mod[i]^Mod[i-1]&&(S.Solve(t,i-1),t=i);return S.PrintAns(),0;//抠出区间分别处理,然后输出答案
}

\(T2\):猪队友

考试时只会写乱搞。

我们可以设\(f_{i,j}\)表示当\(s_i=j\)时使区间\([i,n]\)内\(s\)与\(t\)相同的最小步数,\(g_{i,j}\)表示先使\(s_i=j\),然后使区间\([i+1,n]\)内\(s\)与\(t\)相同的最小步数

然后考虑转移\(f_{i,j}\):

  • 如果枚举的\(j\)与\(t_i\)相同,则我们无需进行操作即可得到\(s_i=t_i\),直接从上一位转移过来,即:\(f_{i,j}=f_{i+1,s_{i+1}}\)。
  • 否则,第一种情况,我们直接替换这一位,即:\(f_{i,j}=f_{i+1,s_{i+1}}+1\)。
  • 第二种情况,如果\(s\)的上一位与\(t\)的这一位相同,则我们可以交换这两位,即:\(f_{i,j}=f_{i+1,j}+1\)。
  • 然后还有第三种比较复杂的情况,即我们先把上一位变成\(t_i\),且保证区间\([i+2,n]\)内\(s\)与\(t\)相同(不难发现,这就相当于\(g_{i+1,t_i}\)),然后我们把上一位与这一位交换(步数加\(1\)),然后比较\(j\)与\(t_{i+1}\)是否恰好相同,如果不同则需要替换\(j\)为\(t_{i+1}\)(步数再加\(1\)),即:\(f_{i,j}=g_{i+1,b_i}+1+[j==b_{i+1}]\)。

\(g_{i,j}\)的转移与其类似。

最后的答案就是\(f_{1,s_1}\),即在\(s_1=s_1\)时,使整个\(s\)与\(t\)相等的步数。

代码如下:

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define C 26
#define Gmin(x,y) (x>(y)&&(x=(y)))
using namespace std;
int n,a[N+5],b[N+5],f[N+5][C+5],g[N+5][C+5];char s[N+5],t[N+5];
int main()
{
    freopen("teammate.in","r",stdin),freopen("teammate.out","w",stdout);
    RI i,j;for(scanf("%s%s",s+1,t+1),n=strlen(s+1),i=1;i<=n;++i) a[i]=s[i]&31,b[i]=t[i]&31;//a与b分别把s与t的字符转化为数字存下来
    for(i=1;i<=C;++i) f[n][i]=b[n]^i?1:0,g[n][i]=a[n]^i?1:0;for(i=n-1;i;--i) for(j=1;j<=C;++j)//初始化状态,然后枚举状态进行转移
    {
        j^b[i]?(f[i][j]=f[i+1][a[i+1]]+1,!(a[i+1]^b[i])&&Gmin(f[i][j],f[i+1][j]+1),Gmin(f[i][j],g[i+1][b[i]]+(j^b[i+1]?1:0)+1)):f[i][j]=f[i+1][a[i+1]];
        j^a[i]?(g[i][j]=g[i+1][b[i+1]]+1,!(a[i+1]^j)&&Gmin(g[i][j],f[i+1][a[i]]+1),Gmin(g[i][j],g[i+1][j]+(a[i]^b[i+1]?1:0)+1)):g[i][j]=g[i+1][b[i+1]];
    }printf("%d",f[1][a[1]]);//输出答案
}

\(T3\):不可能完成的任务

我们首先需要证明两个结论:

  • 结论\(1\):若\(F(a)=t,F(b)=t+C\),则\(a+b=2t-1\)。

    证明如下:

    由\(F(a)=t,F(b)=t+C\)得:

    \[F(a)+C=F(b)\]

    可以发现这与题目中给出的\(F(x)+C=F(2F(x)-x+1)\)类似,对应可得:

    \[a=x,b=2F(x)-x+1,t=F(a)=F(x)\]

    然后代入式子\(a+b\)中计算可得:

    \[a+b=x+(2F(x)-x+1)=2F(x)+1=2t+1\]

  • 结论\(2\):\(F(a+2C)=F(a)+2C\)

    证明如下:

    我们依然像上面一样,设\(F(a')=t',F(b')=t'+C\),依然可得:

    \[F(a')+C=F(b')\]

    两边同时加上一个\(C\),可以得到:

    \[F(a')+2C=F(b')+C\]

    设\(F(c')=F(b')+C\),则\(F(c')=F(a')+2C\)。然后把\(F(c')=F(b')+C\)代入前面的结论\(1\),就可以得到其对应关系为:

    \[a=b',b=c',t=F(a)=F(b')=F(a')+C\]

    因此,我们就可以得到:

    \[b'+c'=2(F(a')+C)+1=2F(a')+2C+1=2t'+2C+1=2C+(2t'+1)\]

    同样由前面的结论\(1\),我们可知\(2t'+1=a'+b'\),代入得:

    \[b'+c'=2C+a'+b'\]

    两边同时减去\(b'\)可得:

    \[c'=a'+2C\]

    代入\(F(c')=F(a')+2C\)可得:

    \[F(a'+2C)=F(a')+2C\]



那么证明这两个结论有什么用呢?

由结论\(2\),我们可知,只要知道\(F\)这个函数在\(0\sim2C-1\)范围内的值,就可以由此推得整个函数的值了。

而由结论\(1\),\(a+b=2t+1\),我们可知,\(a\)与\(b\)的奇偶性显然不同。

若假设\(a\)为偶数,则我们可以设\(a=2x,b=2y+1\),且\(0\le a,b\le2C-1\)。

然后设\(F(a)=t\),则我们需要满足下面这个式子才能使\(a\)和\(b\)成功配对:

\[2F(a)-a+1=b+2nC\]

其中\(n\)为某一未知数。

然后把这个式子移项,可以得到:

\[2F(a)+1=a+b+2nC\]

把\(a=2x,b=2y+1\)代入,可以得到:

\[2F(a)+1=2x+2y+1+2nC\]

两边同减\(1\),然后就能发现系数都为\(2\),然后同除以\(2\)即可得到:

\[F(a)=x+y+nC\]

而\(F(b+2nC)=F(a)+C\),所以:

\[F(b)=F(b+2nC)-2nC=t+C-2nC=x+y+nC+C-2nC=x+y-(n-1)C\]

总结可以得到:

\[F(a)=x+y+nC,F(b)=x+y-(n-1)C\]



接下来我们考虑题目中给出的\(X_i,Y_i\)。

假设\(X_i=a(mod\ 2C)\),则可设:

\[X_i=a+2a_0C\]

因此:

\[F(X_i)=F(a+2a_0C)=F(a)+2a_0C=x+y+nC+2a_0C\]

\[F(X_i)-Y_i=x+y+nC+2a_0C-Y_i\]

假设:

\[W_i=x+y+2a_0C-Y_i\]

所以我们就可以得到:

\[|F(X_i)-Y_i|=|W_i+nC|\]

同理,假设\(X_i=b(mod\ 2C)\),则可设:

\[X_i=b+2b_0C\]

因此:

\[F(X_i)=F(b+2b_0C)=F(b)+2b_0C=x+y-(n-1)C+2b_0C=x+y-nC+(2b_0+1)C\]

\[F(X_i)-Y_i=x+y-nC+(2b_0+1)C-Y_i\]

\[\therefore Y_i-F(X_i)=-x-y+nC-(2b_0+1)C+Y_i\]

假设:

\[W_i=-x-y-(2b_0+1)C+Y_i\]

所以我们就可以得到:

\[|F(X_i)-Y_i|=|Y_i-F(X_i)|=|W_i+nC|\]

于是,最后结果就是\(\sum |W_i+nC|\),显然,根据初一数学可知,\(-nC\)应该尽量接近\(W\)的中位数。

这样,我们就可以求出任意的两个\(x,y\)造成的最小的代价\(p_{x,y}\)。

注意若\(W_i=nC+W'(0\le W'\le C-1)\),则最终使答案最小的应为\(nC\)或者\((n+1)C\)中的一种,需要分别讨论。



接下来,我们要将\(x\)与\(y\)一一配对,就需要做带权二分图匹配

这里我们考虑写一个状压\(DP\),可以设\(f_i\)表示\(y\)已经被匹配的子集为\(i\)时的最小代价

若设\(g_i\)表示\(i\)在二进制下\(1\)的个数,由于\(x\)是按顺序匹配的,则显然此时\(x\)被匹配的是前\(g_i\)个,即第\(0\sim g_i-1\)个。

所以就可以推出转移方程为:

\[f_i=min(f_{i\text{ xor }2^j}+p_{g_i-1,j})\]

具体实现详见代码。



代码如下:

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 10000
#define C 16
#define LL long long
#define Gmin(x,y) (x>(y)&&(x=(y)))
#define INF 1e18
using namespace std;
int n,c,s[N+5],X[N+5],Y[N+5],g[1<<C];LL p[C+5][C+5],f[1<<C];
int main()
{
    freopen("mission.in","r",stdin),freopen("mission.out","w",stdout);
    RI i,j,k,t,px,ax,mx,py,ay,my,S,lim;LL s1,s2;
    scanf("%d%d%d%d%d%d%d%d%d%d",&c,&n,&X[1],&px,&ax,&mx,&Y[1],&py,&ay,&my);//读入
    for(i=2;i<=n;++i) X[i]=(1LL*X[i-1]*px+ax)%mx,Y[i]=(1LL*Y[i-1]*py+ay)%my;//生成数据
    for(i=0;i^c;++i) for(j=0;j^c;++j)//枚举x,y
    {
        for(t=0,k=1;k<=n;++k) X[k]%(c<<1)==(i<<1)?s[++t]=X[k]-Y[k]-i+j:(X[k]%(c<<1)==(j<<1|1)&&(s[++t]=-X[k]+Y[k]-i+j-c+1));//存储W[i]
        if(!t) continue;sort(s+1,s+t+1),S=(s[t+1>>1]%c+c)%c-s[t+1>>1],s1=0,s2=0;//求出中位数
        for(k=1;k<=t;++k) s1+=abs(s[k]+S);for(S-=c,k=1;k<=t;++k) s2+=abs(s[k]+S);p[i][j]=min(s1,s2);//分别讨论nC和(n+1)C,记录任意的两个x,y造成的最小的代价p[x][y]
    }
    for(i=1,lim=1<<c;i^lim;++i) for(g[i]=g[i>>1]+(i&1),f[i]=INF,j=0;j^c;++j) (i>>j)&1&&Gmin(f[i],f[i^(1<<j)]+p[g[i]-1][j]);//状压DP做带权二分图匹配
    return printf("%lld",f[lim-1]),0;//输出答案
}

原文地址:https://www.cnblogs.com/chenxiaoran666/p/Contest20190313.html

时间: 2024-10-14 04:50:38

2019.03.13 ZJOI2019模拟赛 解题报告的相关文章

20161027模拟赛解题报告

20161027模拟赛解题报告 By shenben T1 数学题 模拟即可. 注意开long long T2 技巧题 图片为本题第一张图.(无奈,图传不上来) 首先第一问图中的“Y 字形”的数量,这么简单,在此不细讲. 详见代码 O(n)累加一下就好了 主要说说第二问怎么搞 预处理 每个点分别与其他那些点相连 权值为第1,2,3大(若没有2,3大,就忽略).记录一下权值与对应的点的标号.目的是方便下面的判断. 枚举入度>=3的点,即点B(有多个) 再枚举点B相连的D点(不是点A,C). Ste

20161026模拟赛解题报告

20161026模拟赛解题报告 By shenben T1 按照题目说的模拟即可 但这题有一个神坑:当25个字母都已经一一对应完毕后,剩下的两个字母默认对应. T2 所有的逆序对之间都会连边,求最大独立点集. 表面上是个图论题,其实是个LIS O(nlogn)求最长上升子序列的长度即可AC T3 第一次手贱,用链表存边,这是一个稠密图啊!!应该用邻接矩阵啊. 明明可以用floyed跑,非要dfs乱搞.结果10分.玩砸了吧. 最后只改到了40分. 网上的题解(没看懂): 首先这是一个神奇的图,叫做

10.30 NFLS-NOIP模拟赛 解题报告

总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没码QAQ 现在我来写解题报告了,有点饿了QAQ.. 第一题 题目 1: 架设电话线 [Jeffrey Wang, 2007] 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务,于 是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线.新的电话线架设 在已有的N(2 <=

20161109模拟赛解题报告

2016-11-09试题解题报告 By shenben 本解题报告解析均为100分解题思路. T1 模拟即可. 我怕极限数据5000(n,m)*100000(k). 如果用二维数组.空间勉强撑住,时间上够呛. 因此用2个一位数组分别代表行和列. 这样每次修改是O(1)的. 查询是O(nm)(只查询一次) 总时间复杂度:O(nmk) T2 搜索 一开始想偏了. 倒着由“a”往前推.结果小样例过了,大样例差太多. 于是另辟蹊径. 观察到数据范围很小. 直接枚举答案序列不就好了. 对于每个序列再判断一

2017.9.17校内noip模拟赛解题报告

预计分数:100+60+60=220 实际分数:100+60+40=200 除了暴力什么都不会的我..... T1 2017.9.17巧克力棒(chocolate) 巧克力棒(chocolate)Time Limit:1000ms Memory Limit:64MB题目描述LYK 找到了一根巧克力棒,但是这根巧克力棒太长了,LYK 无法一口吞进去.具体地,这根巧克力棒长为 n,它想将这根巧克力棒折成 n 段长为 1 的巧克力棒,然后慢慢享用.它打算每次将一根长为 k 的巧克力棒折成两段长为 a

0827模拟赛解题报告(16年暑假最后一次模拟赛)

P1061 Jam的计数法 292通过 412提交 题目提供者洛谷OnlineJudge 标签模拟NOIp普及组2006 难度普及/提高- 提交该题 讨论 题解 记录 最新讨论 暂时没有讨论 题目描述 Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原先的顺序,排在前面的字母小于排在它后面的字母.我们把这样的“数字”称为Jam数字.在Jam数字中,每个

9月24日noip模拟赛解题报告

1.校门外的树(tree.c/cpp/pas 128M,1s) Description LSGJ扩建了,于是校门外有了一条长为L的路.路上种了一排的树,每相邻两棵树之间的距离为1,我们可以把马路看成一个数轴,马路的一端在数轴0的位置另一端在数轴L的位置,数轴上的每个整数点都有一棵树. 众所周知,zd是个非常喜欢研究生活中的各种问题的人,zd看到这个现象非常的欣喜,于是他立马就有了一个想法,假如现在要把m个区间内的树全都移走,他想知道最后还剩下多少棵树,由于他刚想出这个问题就被twt拿去一起颓了,

2019/8/27 校内模拟赛 考试报告

A.挑战(challenge.cpp) 首先令\(x_i=max(a_i-k,0)\),即破坏第\(i\)个防御区域的代价. 设\(dp_i\)表示从\(1...i\)需要的最小代价,有状态转移方程:\(dp_i=min(dp_j)+x_i\),其中\(i-L\le j\le i-1\). 初始化边界\(dp_0=0,dp_{1...n+1}=inf\).动态规划求出\(dp_{n+1}\)即可. 时间复杂度\(O(n^2)\),可以用ST表/线段树优化到\(O(nlogn)\). B.乌龟(t

CSU-ACM2014年校队选拔赛指导赛解题报告

•Problem A  CSU 1065                               贪心 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1000010; 6 struct Node{ 7 int a,b; 8 bool operator < (const Node& rhs)