$CH$ $0x50$ & $0x51$ 做题记录

[X]$Mr.Young's\ Picture\ Permutations$

前面这儿写了挺多道辣,,,懒得写辣$QAQ$

(后面所有同上都是同这个$QwQ$

[X]$LCIS$

做过了,看这儿

$upd$:,,,这题有猫饼,不呲呲快读,用快读会$T$一个点,,,然后我下了数据下来发现明明是数据的锅,,,?我感觉它给我的这个数据明明就不够,,,?但反正我改成$scanf$或者$cin$就过去了,,,什么$sd$玩意$QAQ$

[X]$Mobile\ Service$

无脑$dp$入门题,,,?

设$f_{i,j,k}$表示时间$i$没站在$d_{i}$的两个人的坐标,然后只要记得判下说任意俩人不能站在同一个位置就欧克,,,$QwQ$

然后$i$显然是不需要的只是为了方便表述设的这一维,,,实际$code$中是不会有这一维的昂$QwQ$

哦话说,这样儿说着很简单,其实好像是要证个东西,,,就三个人的坐标一定都是移动到$d_{i}$,不可能移动到别的位置,,,$umm$过于显然不证了,,,只是$cue$下其实是要证这个东西的来着$QAQ$

嗷还有一个就,这个$i$显然是要滚掉的嘛,正常方法应该就滚成[0/1]就欧克,然后因为$gql$没有脑子,就直接暴力开了个$f$再开了个$g$,当然显然的是开[0/1]还是好写,因为可以用$memset$,常数应该会小些,,,?不过麻油关系反正过得去就成$bushi$

$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int L=200+10,N=1000+10;
int l,n,f[N][N],g[N][N],pos[L],cst[L][L],as;

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}

int main()
{
    freopen("5102.in","r",stdin);freopen("5102.out","w",stdout);
    l=read();n=read()+3;rp(i,1,l)rp(j,1,l)cst[i][j]=read();pos[1]=1;pos[2]=2;pos[3]=3;memset(f,63,sizeof(f));as=f[0][0];f[1][2]=f[2][1]=0;
    rp(i,4,n)
    {
        pos[i]=read();rp(j,1,l)rp(k,1,l)g[j][k]=f[j][k],f[j][k]=f[0][0];
        rp(j,1,l)
            rp(k,1,l)
            {
                if(j==k)continue;
                if(k!=pos[i] && pos[i-1]!=pos[i])f[k][pos[i-1]]=f[pos[i-1]][k]=min(f[k][pos[i-1]],g[j][k]+cst[j][pos[i]]);
                if(j!=pos[i] && pos[i-1]!=pos[i])f[j][pos[i-1]]=f[pos[i-1]][j]=min(f[j][pos[i-1]],g[j][k]+cst[k][pos[i]]);
                if(j!=pos[i] && k!=pos[i])f[j][k]=f[k][j]=min(f[j][k],g[j][k]+cst[pos[i-1]][pos[i]]);
            }
    }
    rp(i,1,l)rp(j,1,l)if(i!=j && pos[n]!=i && pos[n]!=j)as=min(as,f[i][j]);printf("%d\n",as);
    return 0;
}
View Code

[X]$Making\ the\ Grade$

做过辣,看这儿

[X]传纸条

又双叒是个$dp$无脑入门题,,,?

首先四维$dp$过于显然不想写了,,,

然后考虑四位压成三维,依然太显然了,,,不写辣/$kel\ kel\ kel$

反正大致思路就上面这样儿的,懒得写了$over$

对了,这个$code$是我去年9月份写的了(,,,我那个时候做的题居然这么水,,,?太菜了嘤嘤嘤),,,所以贼丑但我也懒得改了$QAQ$

#include<bits/stdc++.h>
using namespace std;
int a[55][55];
int f[110][55][55];
int read()
{
    char ch;
    int x=0;
    bool o=0;
    ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9'))ch=getchar();
    if(ch=='-')o=1;
    while(ch>='0' && ch<='9')
    {
        x=(x<<3)+(x<<1)+(ch^'0');
        ch=getchar();
    }
    if(o==1)return -x;
    return x;
}
int main()
{
    int m,n;
    m=read();
    n=read();
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)a[i][j]=read();
    memset(f,-1,sizeof(f));
    f[2][1][1]=0;
    for(int k=3;k<m+n;k++)
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
            {
                f[k][i][j]=max(f[k][i][j],max(f[k-1][i][j],max(f[k-1][i-1][j],max(f[k-1][i][j-1],f[k-1][i-1][j-1]))))+a[k-i][i]+a[k-j][j];
                if(f[k][i][j]==a[k-i][i]+a[k-j][j]-1)f[k][i][j]=-1;
            }
    printf("%d",f[m+n-1][n-1][n]);
    return 0;
}
View Code

[X]$I-country$

比起前面几题的话,相对而言还是比较有趣的辣,,,?

$so$大概港下$QwQ$

首先考虑怎么设状态?

首先理解下题意昂,这个所谓凸壳,其实就说要求左端点先递减后递增,右端点先递增后递减

于是显然就考虑状态为$f_{i,j,l,r,0/1,0/1}$,表示选到第$i$行,选了$j$个,左端点到$l$,右端点到$r$,左端点递增递减状态,右端点递增递减状态

转移,表述比较麻烦但并不难想,,,?就先不写辣$QwQ$

欧克然后就做完了,,,然而因为$gql$过于傻逼所以依然$WA$了$inf$次,,,我要死了呜呜呜

想提两个要注意的点$QwQ$

第一个是说,要考虑到可能存在前面若干行不选和后面若干行不选这样儿的情况(像我就非常,没有脑子,直接就又多$for$了下就非常暴力地搞掉了$QwQ$

第二个是说,要注意到还有个隐藏条件,就是相邻两行之间必须有交点,,,记得判下不然会被#4给搞掉应该$QAQ$

嗷还有就是我没写怎么记录方案,,,比较正常的想法应该就过程中瞎搞下应该就欧克了,,,?

然后因为$gql$没有脑子,,,打完才想起来要记录方案,,,然后就懒得瞎搞了,直接在结尾非常暴力地搞了一通,$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=15+10,K=250;
int n,m,kk,dat[N][N],f[N][K][N][N][2][2],sum[N][N],as,prel,prer,opl,opr,tmpn;

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}

signed main()
{
//    freopen("5104.in","r",stdin);freopen("5104.out","w",stdout);
    n=read();m=read();kk=read();rp(i,1,n)rp(j,1,m)sum[i][j]=sum[i][j-1]+(dat[i][j]=read());
    rp(i,1,n)
        rp(j,1,min(m*i,kk))
            rp(l,1,m)
                rp(r,l,m)
                {
                    if(j<r-l+1)continue;
                    f[i][j][l][r][0][0]=f[i][j][l][r][0][1]=f[i][j][l][r][1][0]=f[i][j][l][r][1][1]=sum[i][r]-sum[i][l-1];
                    if(i==1)
                    {
                        if(j!=r-l+1)f[i][j][l][r][0][0]=f[i][j][l][r][0][1]=f[i][j][l][r][1][0]=f[i][j][l][r][1][1]=0;
                        continue;
                    }
                    rp(ll,1,r)
                        rp(rr,l,m)
                        {
                            if(j<rr-ll+1+r-l+1)continue;if(ll>r || l>rr)continue;
                            if(ll>=l)
                            {
                                if(rr>=r)f[i][j][l][r][0][0]=max(max(f[i-1][j-(r-l+1)][ll][rr][0][0],f[i-1][j-(r-l+1)][ll][rr][0][1])+sum[i][r]-sum[i][l-1],f[i][j][l][r][0][0]);
                                if(rr<=r)f[i][j][l][r][0][1]=max(f[i-1][j-(r-l+1)][ll][rr][0][1]+sum[i][r]-sum[i][l-1],f[i][j][l][r][0][1]);
                            }
                            if(ll<=l)
                            {
                                if(rr>=r)f[i][j][l][r][1][0]=max(max(max(f[i-1][j-(r-l+1)][ll][rr][1][0],f[i-1][j-(r-l+1)][ll][rr][1][1]),max(f[i-1][j-(r-l+1)][ll][rr][0][0],f[i-1][j-(r-l+1)][ll][rr][0][1]))+sum[i][r]-sum[i][l-1],f[i][j][l][r][1][0]);
                                if(rr<=r)f[i][j][l][r][1][1]=max(max(f[i-1][j-(r-l+1)][ll][rr][0][1],f[i-1][j-(r-l+1)][ll][rr][1][1])+sum[i][r]-sum[i][l-1],f[i][j][l][r][1][1]);
                            }
                        }
                }
    rp(i,1,n)rp(l,1,m)rp(r,l-1,m){ri tmp=as;as=max(as,max(max(f[i][kk][l][r][0][0],f[i][kk][l][r][0][1]),max(f[i][kk][l][r][1][0],f[i][kk][l][r][1][1])));if(tmp!=as)tmpn=i;}
    printf("Oil : %lld\n",as);
    n=tmpn;
    rp(l,1,m)
        rp(r,l,m)
        {
            if(f[n][kk][l][r][0][0]==as){prel=l,prer=r,opl=0,opr=0;as-=sum[n][r]-sum[n][l-1];kk-=r-l+1;l=m+1;break;}
            if(f[n][kk][l][r][0][1]==as){prel=l,prer=r,opl=0,opr=1;as-=sum[n][r]-sum[n][l-1];kk-=r-l+1;l=m+1;break;}
            if(f[n][kk][l][r][1][0]==as){prel=l,prer=r,opl=1,opr=0;as-=sum[n][r]-sum[n][l-1];kk-=r-l+1;l=m+1;break;}
            if(f[n][kk][l][r][1][1]==as){prel=l,prer=r,opl=1,opr=1;as-=sum[n][r]-sum[n][l-1];kk-=r-l+1;l=m+1;break;}
        }
    rp(i,prel,prer)printf("%lld %lld\n",n,i);
    my(i,n-1,1)
        rp(l,1,m)
            rp(r,l,m)
            {
                if(opl && prel<l)continue;if(!opl && prel>l)continue;if(opr && prer<r)continue;if(!opr && prer>r)continue;if(prel>r || l>prer)continue;
                if(f[i][kk][l][r][0][0]==as)
                    if(!opr)
                    {
                        as-=sum[i][r]-sum[i][l-1];prel=l,prer=r,opl=0,opr=0;kk-=r-l+1;l=m+1;r=m+1;
                        rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
                    }
                if(f[i][kk][l][r][0][1]==as)
                {
                    as-=sum[i][r]-sum[i][l-1];prel=l,prer=r,opl=0,opr=1;kk-=r-l+1;l=m+1;r=m+1;
                    rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
                }
                if(f[i][kk][l][r][1][0]==as)
                    if(opl && !opr)
                    {
                        as-=sum[i][r]-sum[i][l-1];prel=l,prer=r,opl=1,opr=0;kk-=r-l+1;l=m+1;r=m+1;
                        rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
                    }
                if(f[i][kk][l][r][1][1]==as)
                    if(opl)
                    {
                        as-=sum[i][r]-sum[i][l-1];prel=l,prer=r,opl=1,opr=1;kk-=r-l+1;l=m+1;r=m+1;
                        rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
                    }
            }
    return 0;
}
/*
  0:递减
  1:递增
  l:先0后1
  r:先1后0
  0<-0/1 1<-1
  1<-0/1 0<-0
*/
View Code

[X]$Cookies$

这题挺有趣的,,,就这题和之前做过的一道题有点儿像,,,这个,虽然是道绿但我印象还挺深的,,,因为它是这样儿的,就,有一部分之间是无后效性的,但有一部分是有后效性的,,,

这题也是,首先要想到,显然从多往少安排,所以这时候显然有个小小的贪心,就说$g_{i}$越大的拿到的饼干数越多,于是就先按$g_{i}$排个序,然后考虑设$f_{i,j,k}$表示分到第$i$个孩子了,然后分了$j$个饼干,这一个孩子拿了$k$个饼干,看数据范围,发现$O(NM^{2})$,就不太星$QAQ$

好然后再仔细思考下,假如现在有$m$块,显然先平均分,每人拿到$\left \lfloor \frac{m}{n} \right \rfloor$块,这样儿就能把$m$控制在$n$范围以内,就过辣!

然后就被$hack$辣嘤嘤嘤

来我先$hack$下我的无脑优化想法$QAQ$

比如有5个,分别是$inf,inf,inf,inf,0$,然后有13块饼干

如果先贪心,就先均分,每人2个,剩3个,然后这时候$dp$下,显然是前三个每人拿一个,然后代价就是$3\cdot inf$

但是正解应该是,前四个人每人拿3个,然后最后一个人拿1个,这样儿代价就是0,,,

所以就被$hack$了\$kel\ kel\ kel$

而且上面这个还有个问题在于,可以有相等的,就会导致并不知道到底有多少个比它大的$qwq$

好然后现在整个儿都被$hack$了嘤嘤嘤,,,

重写下解法嘤嘤嘤

这里要考虑,状态缩放,也就是通过等价交换使得时间复杂度变好看

先用下万能的分类讨论法$QwQ$

对了先说下,$i$表示的是第$i$个人,$j$表示的是分了$j$块饼干,$k$表示的是从第$k$个人开始所有人都只有1块

1)第$i$个人获得的饼干数>1

这个可以等价与分配$j-i$个饼干给前$i$个人,每人少拿一块,这个显然是等价的$QwQ$,因为相对大小是不变的(这个就和前面那个均分有点儿像,,,是不是$QwQ$

这样儿转移就可以变成,$f_{i,j}=f_{i-1,j-i}$

2)第$i$个人获得的饼干数=1

直接考虑在它及之前有多少个人只有1块?

这样儿转移就可以变成$f_{i,j}=(f_{k,j-(i-k)}+k\cdot \sum_{p=k+1}^{i}g_{p})_{min}$

综上,转移就是$f_{i,j}=(f_{i-1,j-i},(f_{k,j-(i-k)}+k\cdot \sum_{p=k+1}^{i}g_{p})_{min})_{min}$

就做完啦啦啦啦

昂然后最后输出方案,其实我$jio$得还挺有趣的,但我是瞎搞一通搞出来的,也说不出个什么所以然来,就瞎递归下然后模拟($bushi$下就瞎搞出来了,,,所以具体看$code$趴$QAQ$

嗷对了,,,$gql$在线傻逼了一通,,,大概港下$gql$的$sd$想法昂$QAQ$

是这样儿的,就,假如现在是在进行,$i=1$的枚举$k$的转移,然后假如我在转移到$k$的时候,实际上的那个$f_{k,j-(i-k)}$的那个点也是从$k=1$转移来的,那就会导致$f_{i,j}$变大鸭(就因为本来没有$k$个大于1的,但这儿当做有$k$个了嘛$QwQ$

然后仔细一想发现显然是我傻逼了,,,因为如果有这种情况,我一定吃枣会枚举到$k=1$转移来的点${k}'$,然后就一定会从${k}'$这儿再转下,就不会算重了,,,

其实是个很显然的事儿?主要可能还是$gql$太傻逼了嘤嘤嘤

然后因为$gql$语文太差了所以表述能力贼差可能上一段表述得不是很清楚,,,然而我也懒得重写了,,,如果有问题在评论区港就是了$kk$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=30+10,M=5e3+10;
int n,m,g[N],f[N][M],sum[N],pre[N][M],as[N];
struct nod{int g,id;}node[N];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il bool cmp(nod gd,nod gs){return gd.g>gs.g;}
il void work(ri n,ri m)
{
    if(!n)return;
    if(pre[n][m]==n){work(pre[n][m],m-n);rp(i,1,n)++as[node[i].id];return;}
    work(pre[n][m],m-(n-pre[n][m]));rp(i,pre[n][m]+1,n)as[node[i].id]=1;return;
}

int main()
{
    //freopen("5105.in","r",stdin);freopen("5105.out","w",stdout);
    n=read();m=read();rp(i,1,n)node[i]=(nod){read(),i};sort(node+1,node+1+n,cmp);rp(i,1,n)sum[i]=sum[i-1]+node[i].g;memset(f,63,sizeof(f));f[0][0]=0;
    rp(i,1,n)
        rp(j,i,m)
        {
            f[i][j]=f[i][j-i];pre[i][j]=i;
            rp(k,0,i-1)if(f[i][j]>f[k][j-(i-k)]+(sum[i]-sum[k])*k)pre[i][j]=k,f[i][j]=f[k][j-(i-k)]+(sum[i]-sum[k])*k;
        }
    printf("%d\n",f[n][m]);
    work(n,m);
    rp(i,1,n)printf("%d ",as[i]);
    return 0;
}
View Code

[X]数字组合

无脑$dp$,,,?

考虑设$f_{i,j}$表示前$i$个数拼出$j$的方案数,无脑背包下就好,,,?

$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=100+10,M=10000+10;
int n,m,a[N],f[M];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}

int main()
{
    //freopen("5201.in","r",stdin);freopen("5201.out","w",stdout);
    n=read();m=read();rp(i,1,n)a[i]=read();f[0]=1;
    rp(i,1,n)
        my(j,m,a[i])f[j]+=f[j-a[i]];
    printf("%d\n",f[m]);
    return 0;
}
背包板子我居然打了10$min$,,,是不是小水题做多了会影响智商昂$TT$

[X]自然数拆分

又是个无脑$dp$,,,

考虑设$f_{i}$表示拼出$i$的方案数,于是有$f_{i}=\sum f_{j}+f_{i-j}$

$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int M=4000+10,mod=2147483648;
int n,f[M];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}

 main()
{
    //freopen("5202.in","r",stdin);freopen("5202.out","w",stdout);
    n=read();f[0]=1;
    rp(i,1,n)rp(j,i,n)f[j]=(f[j]+f[j-i])%mod;
    printf("%lld\n",f[n]-1>=0?f[n]-1:mod-1);
    return 0;
}
完全背包板子昂$QwQ$

[X]$Jury\ Compromise$

做过了,看这儿

[X]$Coins$

做过了,看这儿

[X]石子合并

无脑区间$dp$

设$f_{l,r}$,表示$[l,r]$的最小代价,做完了

几百年前的代码,贼丑,$QAQ$

$upd:$我在$CH$上交了下,发现题目还是有点儿区别,,,最大的区别在这不是个环,,,所以连断环为链都不需要,,,$QAQ$

$over$

#include<bits/stdc++.h>
using namespace std;
int n,m,a[210],f[222][222],f1[222][222],sum[404],q=0,ww,e,maxl=0,minl=999999999,i,j,l;
int main()
{
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i+n]=a[i];
    }
    for(i=1;i<=2*n;i++)sum[i]=sum[i-1]+a[i];
    for(l=2;l<=n;l++)
    {
        for(i=1;i<=2*n-l+1;i++)
        {
            j=i+l-1;
            f[i][j]=999999;
            f1[i][j]=0;
            for(int k=i;k<=j-1;k++)
            {
                f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);
                f1[i][j]=max(f1[i][j],f1[i][k]+f1[k+1][j]+sum[j]-sum[i-1]);
            }
        }
    }
    for(i=1;i<=n;i++)  
    {  
        maxl=max(maxl,f1[i][i+n-1]);  
        minl=min(minl,f[i][i+n-1]);  
    }  
    cout<<minl<<endl<<maxl;
    return 0;
}
View Code

[X]$Polygon$

做过了,看这儿

[X]金字塔

想到了那个点就不难,不然还是有点儿难度的欸$QAQ$

主要就是要想到一个子树对应一个区间?所以考虑设$f_{l,r}$表示$[l,r]$这个区间作为一颗子树的方案数$QwQ$

然后一个比较有趣的点是考虑怎么转移能保证是不重不漏的$QwQ$,就考虑枚举$[l,r]$中第一颗子树的结束点$k$.然后就有$f_{l,r}=\sum f_{l+1,k-1}\cdot f_{k,r-1}$,当然,还可以从$f_{l-1,r+1}$转移来

综上,就是$f_{l,r}=f_{l-1,r+1}+\sum_{col_{l}=col_{k}}f_{l+1,k-1}\cdot f_{k,r}$(当且仅当col_{l}=col_{r}

记得开$ll$鸭

$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=300+10,mod=1e9;
int n,f[N][N];
char str[N];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il int solve(ri l,ri r)
{
    if(str[l]!=str[r])return 0;if(l>r)return 0;if(l==r)return 1;if(f[l][r]!=-1)return f[l][r];
    f[l][r]=0;
    rp(i,l+2,r-1)if(str[l]==str[r])f[l][r]=(f[l][r]+1ll*solve(l+1,i-1)*solve(i,r)%mod)%mod;
    f[l][r]=(f[l][r]+solve(l+1,r-1))%mod;
    return f[l][r];
}

 main()
{
    //freopen("5302.in","r",stdin);freopen("5302.out","w",stdout);
    scanf("%s",str+1);n=strlen(str+1);memset(f,-1,sizeof(f));
    printf("%lld\n",solve(1,n));
    return 0;
}
View Code

[X]没有上司的舞会

树形$dp$入门题,,,?

很早以前就听说过这题了但一直没做,,,

直接考虑设$f_{i,0/1}$表示考虑了$i$及它的子树了,$i$这个点去不去的最大快乐值

$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=6000+10;
int n,h[N],f[N][2],head[N],ed_cnt,fa[N],rt;
struct ed{int to,nxt;}edge[N];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il void ad(ri to,ri fr){edge[++ed_cnt]=(ed){to,head[fr]};head[fr]=ed_cnt;fa[to]=fr;}
il void solve(ri x){e(i,x)solve(t(i)),f[x][0]+=max(f[t(i)][0],f[t(i)][1]),f[x][1]+=f[t(i)][0];f[x][1]+=h[x];return;}

int main()
{
    //freopen("5401.in","r",stdin);freopen("5401.out","w",stdout);
    n=read();rp(i,1,n)h[i]=read();rp(i,1,n){ri x=read(),y=read();ad(x,y);}
    rp(i,1,n)if(!fa[i])rt=i;solve(rt);printf("%d\n",max(f[rt][0],f[rt][1]));
    return 0;
}
View Code

[X]选课

无脑树形$dp$入门题,,,?

和上一个差不多,状态一样,只是转移有点儿区别,$over$

$over$

然后弱智$gql$就打了$1.5h$才做完,,,身败名裂了$TT$

就,其实这题和上题还是有点儿区别,,,就根本不用设那个0/1的,,,打了我半天我才发现我题意理解错了,,,你们呆我屎猫

其实是个无脑树形背包,,,$get$错了题意自然而然题目类型也判断的是错的昂$QAQ$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=300+10;
int s[N],ed_cnt,head[N],n,m,f[N][N],as;
bool vis[N][N][2];
struct ed{int to,nxt;}edge[N];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il void ad(ri fr,ri to){edge[++ed_cnt]=(ed){to,head[fr]};head[fr]=ed_cnt;}
il void solve(ri x){e(i,x){solve(t(i));my(j,m+1,1)rp(k,0,j-1)f[x][j]=max(f[x][j],f[t(i)][k]+f[x][j-k]);}}

int main()
{
    freopen("2014.in","r",stdin);freopen("2014.out","w",stdout);
    n=read();m=read();
    rp(i,1,n)ad(read(),i),f[i][1]=read();
    solve(0);printf("%d\n",f[0][m+1]);
    return 0;
}
View Code

[ ]$Accumulation\ Degree$

这儿

[X]$Naptime$

做过了,看这儿

[X]环路运输

考虑先断环为链并日常长度×2?

然后考虑这道题变成了什么样儿?就,求$max(A_{i}+A_{j}+i-j)$,其中$i\leq 2\cdot n,j\leq 2\cdot n,i-j\leq \frac{n}{2}$

考虑枚举$i$,然后现在就是要求$max(A_{j}-j)$,显然考虑单调队列?

这样儿复杂度均摊下来就差不多是$O(n)$的,$over$

话说这真的是个$dp$,,,?

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)

const int N=1e6+10;
int n,a[N<<1],que[N<<1],head,tail,as;

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
struct gdgs
{
    int que[N<<1],head,tail;
    gdgs(){head=1,tail=0;}
    il int top(){return a[que[head]]-que[head];}
    il void push(ri x){while(a[que[tail]]-que[tail]<=a[x]-x && tail>=head)--tail;que[++tail]=x;}
    il void clr(ri x){while(que[head]<x && tail>=head)++head;}
}qwq;

int main()
{
    //freopen("5501.in","r",stdin);freopen("5501.out","w",stdout);
    n=read();rp(i,1,n)a[i]=a[i+n]=read();
    rp(i,1,n<<1)
    {
        qwq.clr(i-n/2);
        if(i>=n)as=max(as,a[i]+i+qwq.top());qwq.push(i);
    }
    printf("%d\n",as);
    return 0;
}
View Code

[X]$Broken\ Robot$

做过了,看这儿

[X]$Mondriaan's\ Dream$

做过了,看这儿

[X]炮兵阵地

做过了,看这儿

[X]开车旅行

很久以前就想做了,,,然后一直没做嘤嘤嘤

考虑预处理出从每个城市$i$出发,小$A$和小$B$分别会去的第一个城市,记为$nxta_{i}$和$nxtb_{i}$

然后考虑再设个$f_{i,j,0/1}$表示从$i$出发,经过$2^{j}$个城市,从小A/小B开始最终到的城市,$l_{a/b,i,j,0/1}$表示路程

显然瞎倍增转移下就好,,,

然后后面也瞎倍增下就做完辣,,

$over$

昂然后首先第一个难点就在预处理,,,这儿有三个方法,一个是用$set$,一个是用双向链表,还一个是用$splay$.因为挺久没练$splay$了,所以估计我之后放的$code$会是$set$版本的,,,?但这两种方法还是都会港下的$QwQ$

首先港下$set$的趴$QwQ$,考虑从后往前加入$set$,顺便把每个点的后边的最近和次近的点就能直接找到了,$over$

双向链表的思路比较类似,但感觉复杂度也许好看些,,,?感觉而已$QwQ$大致思路是先排序,然后考虑从前往后找,显然对第一个点来说所有点都在它后边,于是就能很轻松地找到第一个点的$nxt$,然后就把第一个点删了,这样第二个点就变成第一个点了,这么做下去就好鸭$QwQ$

$splay$其实也差不多鸭$QwQ$和$set$一样儿的思想,然后直接查询$pre$和$nxt$就好$QwQ$

$umm$倍增还是详细点儿港趴,,,

首先还是解释下那几个预处理的数组的意思_(:з」∠)_

其实$f$是比较好解释的$QwQ$?$f_{i,j,0}$指小$a$走第一步,以$i$为起点,走$2^{j}$到达的城市.$f_{i,j,1}$指小$b$走第一步

然后这个$l$我大概港下$QwQ$,其实也还是挺好解释的来着$QwQ$.$l_{a,i,j,0}$指小$a$走第一步,以$i$为起点,走$2^{j}$,小$a$走的路程.$l_{a,i,j,1}$指小$a$走第一步,小$b$走的路程.$l_{b,i,j,0}$指小$b$走第一步,小$a$走的路程,$l_{b,i,j,1}$指小$b$走第一步,小$b$走的路程

变量有点儿多但思路还是挺顺的嘛$QwQ$

然后瞎转移就成$QwQ$,另外,记得特判边界昂$QwQ$

还有一个小细节,是在转移的时候,不难发现,因为$2^{i}$为偶数,所以从谁出发的走了$2^{i}$之后依然是从谁出发.但这儿有个细节,就当$i=1$的时候,因为它实际上是拆成$2^{i-1}$和$2^{i-1}$,就会导致出现奇数,也就是说变为从谁出发转移中就变为另一个人出发,所以对$i=1$要提前处理掉,不能一块儿做昂$QwQ$

真·over?

 

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define lf double
#define int long long
#define gc getchar()
#define mp make_pair
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)

const int N=100000+10,inf=1e9+10;const lf eps=1e-9;
int n,h[N],f[N][20][2],la[N][20][2],lb[N][20][2],as1,as2,as;
lf tmp_as;

il int read()
{
    ri x=0;rb y=1;rc ch=gc;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
namespace gdgs
{
    int rt,nod_cnt;
    struct node{int fa,ch[2],val,cnt,sz,nam;il void pre(ri x,ri fat,ri name){ch[0]=ch[1]=0;fa=fat;val=x;cnt=sz=1;nam=name;}}tr[N];
    struct qwq{int nam,hei;}qaq[5];
    il int abs(ri x){return x>0?x:-x;}
    il bool cmp(qwq gd,qwq gs){return abs(gd.hei)==abs(gs.hei)?gd.hei<gs.hei:abs(gd.hei)<abs(gs.hei);}
    il void pushup(ri x){tr[x].sz=tr[tr[x].ch[0]].sz+tr[tr[x].ch[1]].sz+tr[x].cnt;}
    il void rotate(ri x)
    {
        ri fa=tr[x].fa,grdfa=tr[fa].fa;bool op1=tr[fa].ch[1]==x,op2=tr[grdfa].ch[1]==fa;
        tr[grdfa].ch[op2]=x;tr[x].fa=grdfa;
        tr[fa].ch[op1]=tr[x].ch[op1^1];tr[tr[x].ch[op1^1]].fa=fa;
        tr[fa].fa=x;tr[x].ch[op1^1]=fa;
        pushup(fa);pushup(x);
    }
    il void splay(ri x,ri goal)
    {
        while(tr[x].fa!=goal)
        {
            ri fa=tr[x].fa,grdfa=tr[fa].fa;
            if(grdfa!=goal)(tr[fa].ch[0]==x)^(tr[grdfa].ch[0]==fa)?rotate(x):rotate(fa);
            rotate(x);
        }
        if(!goal)rt=x;
    }
    il void insert(ri x,ri nam)
    {
        ri nw=rt,fa=0;
        while(nw && tr[nw].val!=x)fa=nw,nw=tr[nw].ch[x>tr[nw].val];
        nw=++nod_cnt;if(fa)tr[fa].ch[x>tr[fa].val]=nod_cnt;tr[nod_cnt].pre(x,fa,nam);
        splay(nw,0);
    }
    il void fd(ri x){ri nw=rt;if(!nw)return;while(tr[nw].ch[x>tr[nw].val] && x!=tr[nw].val)nw=tr[nw].ch[x>tr[nw].val];splay(nw,0);}
    il int ask_pr(ri x){fd(x);ri nw=tr[rt].ch[0];while(tr[nw].ch[1])nw=tr[nw].ch[1];return nw;}
    il int ask_nxt(ri x){fd(x);ri nw=tr[rt].ch[1];while(tr[nw].ch[0])nw=tr[nw].ch[0];return nw;}
    il void pre_nxt()
    {
        insert(inf,0);insert(inf+1,0);insert(-inf,0);insert(-inf-1,0);f[n-1][0][1]=n;lb[n-1][0][1]=abs(h[n]-h[n-1]);insert(h[n],n);insert(h[n-1],n-1);
        my(i,n-2,1)
        {
            insert(h[i],i);
            qaq[1].nam=tr[ask_pr(h[i])].nam,qaq[1].hei=h[qaq[1].nam]-h[i];
            qaq[2].nam=tr[ask_pr(h[qaq[1].nam])].nam;qaq[2].hei=h[qaq[2].nam]-h[i];
            qaq[3].nam=tr[ask_nxt(h[i])].nam,qaq[3].hei=h[qaq[3].nam]-h[i];
            qaq[4].nam=tr[ask_nxt(h[qaq[3].nam])].nam;qaq[4].hei=h[qaq[4].nam]-h[i];
            sort(qaq+1,qaq+1+4,cmp);
            f[i][0][1]=qaq[1].nam;f[i][0][0]=qaq[2].nam;lb[i][0][1]=abs(qaq[1].hei);la[i][0][0]=abs(qaq[2].hei);
        }
    }
}
il void pre()
{
    rp(i,1,n)
    {
        f[i][1][0]=f[f[i][0][0]][0][1];f[i][1][1]=f[f[i][0][1]][0][0];
        if(f[i][1][0])la[i][1][0]=la[i][0][0],la[i][1][1]=lb[f[i][0][0]][0][1];
        if(f[i][1][1])lb[i][1][1]=lb[i][0][1],lb[i][1][0]=la[f[i][0][1]][0][0];
    }
    for(ri j=2;((1<<j)|1)<=n;++j)
        rp(i,1,n-(1<<j))
        {
            f[i][j][0]=f[f[i][j-1][0]][j-1][0];f[i][j][1]=f[f[i][j-1][1]][j-1][1];
            if(f[i][j][0])la[i][j][0]=la[i][j-1][0]+la[f[i][j-1][0]][j-1][0],la[i][j][1]=la[i][j-1][1]+la[f[i][j-1][0]][j-1][1];
            if(f[i][j][1])lb[i][j][0]=lb[i][j-1][0]+lb[f[i][j-1][1]][j-1][0],lb[i][j][1]=lb[i][j-1][1]+lb[f[i][j-1][1]][j-1][1];
        }
}
il void query(ri x,ri dis,ri &as1,ri &as2,rb y)
{
    //printf("x=%d dis=%d as1=%d as2=%d y=%d\n",x,dis,as1,as2,y);
    if(!y)
    {
        my(i,19,0)
            if(f[x][i][0] && la[x][i][0]+la[x][i][1]<=dis)
            {dis-=la[x][i][0]+la[x][i][1];as1+=la[x][i][0];as2+=la[x][i][1];/*printf("  i=%d\n",i);*/query(f[x][i][0],dis,as1,as2,y^(i==0));return;}
    }
    else
    {
        my(i,19,0)
            if(f[x][i][1] && lb[x][i][0]+lb[x][i][1]<=dis)
            {dis-=lb[x][i][0]+lb[x][i][1];as1+=lb[x][i][0];as2+=lb[x][i][1];/*printf("  i=%d\n",i);*/query(f[x][i][1],dis,as1,as2,y^(i==0));return;}
    }
}

 main()
{
    //freopen("1081.in","r",stdin);freopen("1081.out","w",stdout);
    n=read();rp(i,1,n)h[i]=read();h[0]=inf;gdgs::pre_nxt();pre();
    //rp(j,0,3)rp(i,1,n)printf("(%d,%d) a:f=%d la=%d lb=%d b:f=%d la=%d lb=%d\n",i,j,f[i][j][0],la[i][j][0],la[i][j][1],f[i][j][1],lb[i][j][0],lb[i][j][1]);
    /*预处理麻油问题!yep!*/
    ri x=read();tmp_as=inf;
    rp(i,1,n)
    {
        ri as1=0,as2=0;lf tmp;query(i,x,as1,as2,0);
        //printf("i=%d as1=%d as2=%d\n",i,as1,as2);
        if(!as2)continue;
        tmp=(lf)as1/as2;
        if(tmp_as>tmp)tmp_as=tmp,as=i;
        else if(abs(tmp_as-tmp)<=eps && h[i]>h[as])as=i;
    }
    printf("%lld\n",as);
    ri m=read();
    while(m--){ri s=read(),x=read(),as1=0,as2=0;query(s,x,as1,as2,0);printf("%lld %lld\n",as1,as2);}
    return 0;
}
View Code

 

[X]$Count\ The\ Repetitions$

感觉这题长得很像做过的样子,,,但找了半天就是没找到是为什么嘤嘤嘤

$umm$有人不能发现$conn(conn(s_2,n_2 ),m)$就是$conn(s_{2},n_2\cdot m)$嘛,,,?

所以可以考虑先求出一个$ {m}' $表示$ conn ( s_{2} , {m}' ) $不能用$ conn(s_{1} , n_{1}) $生成,然后直接就能求出$m$辣$QwQ$

欧克现在就考虑怎么求这个${m}'$,因为打起来挺麻烦我后面就都用$m$表示辣,,,也就说后面所有$m$表示的都${m}'$昂$QwQ$

然后因为后文中的$n_{2}$也就完全麻油意义辣,所以后文所有$n_{1}$都写成$n$,也就说$后面所有n$表示的都$n_{1}$鸭$QwQ$

然后现在发现$m$可能很大,上界是$\frac{|s_{1}|\cdot n_{1}}{|s_{2}|}$,于是考虑先二进制拆分掉,就,假如$m=2^{p_{1}}+2^{p_{2}}+2^{p_{3}}+...$,就可以当做$conn(s_{2},m)$是由$conn(s_{2},2^{p_{1}}),conn(s_{2},2^{p_{2}}),...$拼起来这样儿的

然后还有一个是$n$也挺大的吼,这里可以先假设$n$足够大,即$s_{1}$重复了无数次

然后考虑设$f_{i,j}$表示从$s_{1}[i]$开始,能生成$conn(s_{2},2^{j})$的最少字符数

显然转移有$f_{i,j}=f_{i,j-1}+f_{(i+f_{i,j-1})\ mod\ |s_{1}|,j-1}$

十分显然懒得解释了,,,

然后瞎预处理一通就欧克$QwQ$

然后最后求答案同样瞎搞一通($bushi$就做完辣,,,

$over$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define lf double
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)

const int N=1000+10;
int n,f[N][35],tot_len,len1,len2,m;
char s1[N],s2[N];

il int read()
{
    ri x=0;rb y=1;rc ch=gc;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il bool pre()
{
    rp(i,0,len1-1)
    {ri pos=i;rp(j,0,len2-1){ri cnt=0;while(s1[pos]!=s2[j]){++pos;pos%=len1;++cnt;if(cnt>len1)return printf("0\n"),0;}++pos;pos%=len1;f[i][0]+=cnt+1;}}
    rp(j,1,27)rp(i,0,len1-1)f[i][j]=f[i][j-1]+f[(i+f[i][j-1])%len1][j-1];
    return 1;
}

 main()
{
    while(~scanf("%s",s2))
    {
        memset(f,0,sizeof(f));
        ri n2=read();scanf("%s",s1);n=read();len1=strlen(s1);len2=strlen(s2);tot_len=len1*n;m=0;
        if(!pre())continue;ri pos=0;my(i,27,0)if(f[pos][i]<=tot_len){/*printf("tot_len=%d f[%d][%d]=%d\n",tot_len,pos,i,f[pos][i]);*/tot_len-=f[pos][i],m+=1<<i,pos+=f[pos][i],pos%=len1;}
        printf("%lld\n",m/n2);
    }
    return 0;
}
View Code

[ ]$Cleaning\ Shifts$

无脑$dp$,只是要数据结构优化下

话说我还没做过数据结构优化$dp$的题目,,,只听说过,,,所以还挺新奇的嘿$QwQ$

首先显然考虑无脑$dp$怎么搞?

就$f_{i}$表示搞到$i$了的最小代价

转移就$f_{r_{i}}=(f_{x})_{min}+c_{i}$,其中$x\in [l_{i}-1,r_{i]}$

区间最值这种不显然线段树维护就好,,,?

$over$

哦然后一个$attention$,就,这题还挺友好的,坐标范围很小,就直接做就好,否则是要离散化的昂$QwQ

口胡完感$jio$很$easy$的亚子,咕了,$QwQ$

[X]$The\ Battle\ of\ Chibi$

先不考虑数据范围,思考怎么做

设$f_{i,j}$表示以$i$结尾长度为$j$的最长上升子序列个数

转移显然就$f_{i,j}=\sum f_{k,j-1},a_{k}<a_{i}$

然后考虑转移顺序?就$j$在外层$i$在内层.

然后现在的问题在于,数据范围比较大,如果枚举$k$显然会超时$kk$

所以现在就是要优化这个计算$k$的过程

考虑因为$j$在外层,可以先当作$j$是定值,就有$f_{i}=\sum f_{k},a_{k}<a_{i}$

不难想到树状数组?

于是就树状数组优化下就做完了$QwQ$

还有个就,$a_{i}$的范围挺大的,记得离散化昂

 

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define lf double
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define lowbit(x) (x&(-x))
#define lb(x) lower_bound(st+1,st+1+st_cnt,x)-st

const int N=1000+10,mod=1e9+7;
int n,m,a[N],f[N][N],st[N],st_cnt,cnt,tr[N];

il int read()
{
    ri x=0;rb y=1;rc ch=gc;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
il void ad(ri x,ri dat){while(x<=st_cnt)tr[x]=(tr[x]+dat)%mod,x+=lowbit(x);}
il int query(ri x){ri ret=0;while(x){ret=(ret+tr[x])%mod;x-=lowbit(x);}return ret;}

 main()
{
    ri T=read();
    while(T--)
    {
        printf("Case #%lld: ",++cnt);memset(f,0,sizeof(f));
        n=read();m=read();rp(i,1,n)a[i]=st[i]=read();sort(st+1,st+1+n);st_cnt=unique(st+1,st+1+n)-st-1;rp(i,1,n)a[i]=lb(a[i]),f[i][1]=1;
        rp(j,2,m){memset(tr,0,sizeof(tr));rp(i,1,n)f[i][j]=query(a[i]-1),ad(a[i],f[i][j-1]);}
        ri as=0;rp(i,1,n)as=(as+f[i][m])%mod;printf("%lld\n",as);
    }
    return 0;
}
View Code

 

[X]$Fence$

做过了,看这儿

[ ]$cut\ the\ sequence$

咕了,下午写$QAQ$

[ ]任务安排

这儿

[ ]任务安排2

这儿

[ ]任务安排3

太菜了不会斜率优化,咕了

[X]$cats\ trandsport$

这儿

[ ]诗人小$G$

神奇四边形不等式在哪里?

不会,咕了

欢迎催更$QwQ$

反正我也不会写的($bushi$

[ ]再探石子合并

$umm$就数据范围++

于是用个四边形不等式就好

然而我不会

所以会详细写的$QwQ$

[ ]$Gerald\ and\ Giant\ Chess$

本来是可以无脑$dp$的,,,

但是数据范围太大辣$kk$,考虑转化这道题

不难发现,如果没有黑色格子,从左上到右下的方案一个组合数就出来辣$QwQ$

然后就只要求出从左上到右下至少经过一个黑色棋子的方案了$QwQ$

考虑设$f_{i}$表示从左上角走到第$i$个黑色棋子的方案数,用组合数+容斥瞎转移下就好,,,

$over$

[ ]$Connected\ Graph$

这儿

[ ]$hwo\ many\ of\ them?$

挺神的我$jio$得,,,没看书上题解我真没想到$kk$

考虑设$f_{i,j}$表示$i$个点构成的包含$j$条割边的无向连通图数量

然后计数类$dp$呢,有个基本思想,是这样儿的,下课了咕了下午写$QAQ$

[X]$A\ Decorative\ Fence$

这儿

[X]乌龟棋

无脑$dp$

考虑设$f_{i,j,k,p,q}$表示每张牌剩余的数量

$over$

很久以前的$code$了,贼丑$QAQ$

#include<bits/stdc++.h>
using namespace std;
int n,m,s[400],c[5],dp[41][41][41][41];
bool o;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)cin>>s[i];
    for(int i=1;i<=m;i++)
    {
        int t;
        cin>>t;
        c[t]++;
    }
    dp[0][0][0][0]=s[1];
    for(int i=0;i<=c[1];i++)
        for(int j=0;j<=c[2];j++)
            for(int k=0;k<=c[3];k++)
                for(int p=0;p<=c[4];p++)
                {
                    if(i>0)dp[i][j][k][p]=max(dp[i-1][j][k][p]+s[i+j*2+k*3+p*4+1],dp[i][j][k][p]);
                    if(j>0)dp[i][j][k][p]=max(dp[i][j-1][k][p]+s[i+j*2+k*3+p*4+1],dp[i][j][k][p]);
                    if(k>0)dp[i][j][k][p]=max(dp[i][j][k-1][p]+s[i+j*2+k*3+p*4+1],dp[i][j][k][p]);
                    if(p>0)dp[i][j][k][p]=max(dp[i][j][k][p-1]+s[i+j*2+k*3+p*4+1],dp[i][j][k][p]);
//                    cout<<"i="<<i<<" j="<<j<<" k="<<k<<" p="<<p<<" dp="<<dp[i][j][k][p]<<endl;
                }
    cout<<dp[c[1]][c[2]][c[3]][c[4]];
    return 0;
}
View Code

[X]花店橱窗

无脑$dp$

甚至连题解都不想写

直接看$code$趴,,,

#include<bits/stdc++.h>
using namespace std;
long long a[1005],n,i,j,k,ans[1005][1005],maxans;
int main()
{
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i+n]=a[i];
    }
    for(i=2;i<2*n;i++)
        for(j=i-1;j>=1 && i-j<n;j--)
        {
            for(k=j;k<i;k++)
                ans[j][i]=max(ans[j][i],ans[j][k]+ans[k+1][i]+a[i+1]*a[k+1]*a[j]);
            maxans=max(maxans,ans[j][i]);
        }
    cout<<maxans;
    return 0;
}
View Code

[ ]$Buy\ Low\ Buy\ Lower$

[ ]$Trip$

[ ]$Substract$

[ ]陨石的秘密

[ ]划分大理石

[ ]$Folding$

[X]能量项链

无脑区间$dp$,瞎搞下就好,,,?

懒得写了入门题没什么可写的昂$QAQ$

很久以前的代码,丑,没了

#include<bits/stdc++.h>
using namespace std;
long long a[1005],n,i,j,k,ans[1005][1005],maxans;
int main()
{
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i+n]=a[i];
    }
    for(i=2;i<2*n;i++)
        for(j=i-1;j>=1 && i-j<n;j--)
        {
            for(k=j;k<i;k++)
                ans[j][i]=max(ans[j][i],ans[j][k]+ans[k+1][i]+a[i+1]*a[k+1]*a[j]);
            maxans=max(maxans,ans[j][i]);
        }
    cout<<maxans;
    return 0;
}
View Code

[ ]棋盘分割

[X]$Blocks$

叶佬在$NOIp$的时候讲过,所以那时候就落实了$QwQ$

显然区间$dp$?就设$f_{l,r,k}$,表示的$[l,r]$这个颜色区间,然后右侧还有$k$个和$col_{j}$颜色相同的格子的最大贡献(为什么还会有这个$k$呢,挺显然的还$QwQ$,就因为可能有一段中间被消了之后就会出现拖家带口($bushi$)这种情况辣$QwQ$

好像解释得不太清,,,不管了懒得解释了$QAQ$,如果有没$get$的在下面留言下啥的我再重新港下,,,$QAQ$

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,l,r) for(ri i=l;i<=r;++i)
#define my(i,l,r) for(ri i=l;i>=r;--i)

const int N=210;
int n,color[N],cnt[N],f[N][N][N],now,ct,ans;

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
    if(ch=='-')ch=gc,y=0;
    while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
    return y?x:-x;
}
int bfs(int l,int r,int k)
{
    if(f[l][r][k]!=0)return f[l][r][k];if(l>r)return 0;
    f[l][r][k]=bfs(l,r-1,0)+(cnt[r]+k)*(cnt[r]+k);
    rp(i,l,r-1)if(color[i]==color[r])f[l][r][k]=max(bfs(l,i,cnt[r]+k)+bfs(i+1,r-1,0),f[l][r][k]);
    return f[l][r][k];
}

int main()
{
//    freopen("QAQ.in","r",stdin);freopen("QAQ.out","w",stdout);
    ri T=read();
    rp(i,1,T)
    {
        memset(color,0,sizeof(color));memset(f,0,sizeof(f));now=1;n=read();
        rp(j,1,n){ct=read();if(ct==color[now])++cnt[now];else{++now;cnt[now]=1;color[now]=ct;}}
        ans=bfs(1,now,0);
        cout<<"Case "<<i<<": "<<ans<<endl;
    }
    return 0;
} 
View Code

[ ]$Strategic\ game$

[ ]$Bugs\ Integrated\ Inc$

[ ]$Fence\ Obstacle\ Course$

[ ]$K-Anonymous\ Sequence$

[ ]$Post\ Office$

[ ]扑克牌

[ ]$The\ Counting\ Problem$

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值