[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$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define gc getchar()
  5. #define t(i) edge[i].to
  6. #define ri register int
  7. #define rb register bool
  8. #define rc register char
  9. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  10. #define my(i,l,r) for(ri i=l;i>=r;--i)
  11. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  12.  
  13. const int L=+,N=+;
  14. int l,n,f[N][N],g[N][N],pos[L],cst[L][L],as;
  15.  
  16. il int read()
  17. {
  18. rc ch=gc;ri x=;rb y=;
  19. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  20. if(ch=='-')ch=gc,y=;
  21. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  22. return y?x:-x;
  23. }
  24.  
  25. int main()
  26. {
  27. freopen("5102.in","r",stdin);freopen("5102.out","w",stdout);
  28. l=read();n=read()+;rp(i,,l)rp(j,,l)cst[i][j]=read();pos[]=;pos[]=;pos[]=;memset(f,,sizeof(f));as=f[][];f[][]=f[][]=;
  29. rp(i,,n)
  30. {
  31. pos[i]=read();rp(j,,l)rp(k,,l)g[j][k]=f[j][k],f[j][k]=f[][];
  32. rp(j,,l)
  33. rp(k,,l)
  34. {
  35. if(j==k)continue;
  36. if(k!=pos[i] && pos[i-]!=pos[i])f[k][pos[i-]]=f[pos[i-]][k]=min(f[k][pos[i-]],g[j][k]+cst[j][pos[i]]);
  37. if(j!=pos[i] && pos[i-]!=pos[i])f[j][pos[i-]]=f[pos[i-]][j]=min(f[j][pos[i-]],g[j][k]+cst[k][pos[i]]);
  38. if(j!=pos[i] && k!=pos[i])f[j][k]=f[k][j]=min(f[j][k],g[j][k]+cst[pos[i-]][pos[i]]);
  39. }
  40. }
  41. rp(i,,l)rp(j,,l)if(i!=j && pos[n]!=i && pos[n]!=j)as=min(as,f[i][j]);printf("%d\n",as);
  42. return ;
  43. }

[X]$Making\ the\ Grade$

做过辣,看这儿

[X]传纸条

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

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

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

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

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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[][];
  4. int f[][][];
  5. int read()
  6. {
  7. char ch;
  8. int x=;
  9. bool o=;
  10. ch=getchar();
  11. while(ch!='-' && (ch<'' || ch>''))ch=getchar();
  12. if(ch=='-')o=;
  13. while(ch>='' && ch<='')
  14. {
  15. x=(x<<)+(x<<)+(ch^'');
  16. ch=getchar();
  17. }
  18. if(o==)return -x;
  19. return x;
  20. }
  21. int main()
  22. {
  23. int m,n;
  24. m=read();
  25. n=read();
  26. for(int i=;i<=m;i++)
  27. for(int j=;j<=n;j++)a[i][j]=read();
  28. memset(f,-,sizeof(f));
  29. f[][][]=;
  30. for(int k=;k<m+n;k++)
  31. for(int i=;i<n;i++)
  32. for(int j=i+;j<=n;j++)
  33. {
  34. f[k][i][j]=max(f[k][i][j],max(f[k-][i][j],max(f[k-][i-][j],max(f[k-][i][j-],f[k-][i-][j-]))))+a[k-i][i]+a[k-j][j];
  35. if(f[k][i][j]==a[k-i][i]+a[k-j][j]-)f[k][i][j]=-;
  36. }
  37. printf("%d",f[m+n-][n-][n]);
  38. return ;
  39. }

[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$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define int long long
  5. #define gc getchar()
  6. #define t(i) edge[i].to
  7. #define ri register int
  8. #define rb register bool
  9. #define rc register char
  10. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  11. #define my(i,l,r) for(ri i=l;i>=r;--i)
  12. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  13.  
  14. const int N=+,K=;
  15. int n,m,kk,dat[N][N],f[N][K][N][N][][],sum[N][N],as,prel,prer,opl,opr,tmpn;
  16.  
  17. il int read()
  18. {
  19. rc ch=gc;ri x=;rb y=;
  20. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  21. if(ch=='-')ch=gc,y=;
  22. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  23. return y?x:-x;
  24. }
  25.  
  26. signed main()
  27. {
  28. // freopen("5104.in","r",stdin);freopen("5104.out","w",stdout);
  29. n=read();m=read();kk=read();rp(i,,n)rp(j,,m)sum[i][j]=sum[i][j-]+(dat[i][j]=read());
  30. rp(i,,n)
  31. rp(j,,min(m*i,kk))
  32. rp(l,,m)
  33. rp(r,l,m)
  34. {
  35. if(j<r-l+)continue;
  36. f[i][j][l][r][][]=f[i][j][l][r][][]=f[i][j][l][r][][]=f[i][j][l][r][][]=sum[i][r]-sum[i][l-];
  37. if(i==)
  38. {
  39. if(j!=r-l+)f[i][j][l][r][][]=f[i][j][l][r][][]=f[i][j][l][r][][]=f[i][j][l][r][][]=;
  40. continue;
  41. }
  42. rp(ll,,r)
  43. rp(rr,l,m)
  44. {
  45. if(j<rr-ll++r-l+)continue;if(ll>r || l>rr)continue;
  46. if(ll>=l)
  47. {
  48. if(rr>=r)f[i][j][l][r][][]=max(max(f[i-][j-(r-l+)][ll][rr][][],f[i-][j-(r-l+)][ll][rr][][])+sum[i][r]-sum[i][l-],f[i][j][l][r][][]);
  49. if(rr<=r)f[i][j][l][r][][]=max(f[i-][j-(r-l+)][ll][rr][][]+sum[i][r]-sum[i][l-],f[i][j][l][r][][]);
  50. }
  51. if(ll<=l)
  52. {
  53. if(rr>=r)f[i][j][l][r][][]=max(max(max(f[i-][j-(r-l+)][ll][rr][][],f[i-][j-(r-l+)][ll][rr][][]),max(f[i-][j-(r-l+)][ll][rr][][],f[i-][j-(r-l+)][ll][rr][][]))+sum[i][r]-sum[i][l-],f[i][j][l][r][][]);
  54. if(rr<=r)f[i][j][l][r][][]=max(max(f[i-][j-(r-l+)][ll][rr][][],f[i-][j-(r-l+)][ll][rr][][])+sum[i][r]-sum[i][l-],f[i][j][l][r][][]);
  55. }
  56. }
  57. }
  58. rp(i,,n)rp(l,,m)rp(r,l-,m){ri tmp=as;as=max(as,max(max(f[i][kk][l][r][][],f[i][kk][l][r][][]),max(f[i][kk][l][r][][],f[i][kk][l][r][][])));if(tmp!=as)tmpn=i;}
  59. printf("Oil : %lld\n",as);
  60. n=tmpn;
  61. rp(l,,m)
  62. rp(r,l,m)
  63. {
  64. if(f[n][kk][l][r][][]==as){prel=l,prer=r,opl=,opr=;as-=sum[n][r]-sum[n][l-];kk-=r-l+;l=m+;break;}
  65. if(f[n][kk][l][r][][]==as){prel=l,prer=r,opl=,opr=;as-=sum[n][r]-sum[n][l-];kk-=r-l+;l=m+;break;}
  66. if(f[n][kk][l][r][][]==as){prel=l,prer=r,opl=,opr=;as-=sum[n][r]-sum[n][l-];kk-=r-l+;l=m+;break;}
  67. if(f[n][kk][l][r][][]==as){prel=l,prer=r,opl=,opr=;as-=sum[n][r]-sum[n][l-];kk-=r-l+;l=m+;break;}
  68. }
  69. rp(i,prel,prer)printf("%lld %lld\n",n,i);
  70. my(i,n-,)
  71. rp(l,,m)
  72. rp(r,l,m)
  73. {
  74. 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;
  75. if(f[i][kk][l][r][][]==as)
  76. if(!opr)
  77. {
  78. as-=sum[i][r]-sum[i][l-];prel=l,prer=r,opl=,opr=;kk-=r-l+;l=m+;r=m+;
  79. rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
  80. }
  81. if(f[i][kk][l][r][][]==as)
  82. {
  83. as-=sum[i][r]-sum[i][l-];prel=l,prer=r,opl=,opr=;kk-=r-l+;l=m+;r=m+;
  84. rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
  85. }
  86. if(f[i][kk][l][r][][]==as)
  87. if(opl && !opr)
  88. {
  89. as-=sum[i][r]-sum[i][l-];prel=l,prer=r,opl=,opr=;kk-=r-l+;l=m+;r=m+;
  90. rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
  91. }
  92. if(f[i][kk][l][r][][]==as)
  93. if(opl)
  94. {
  95. as-=sum[i][r]-sum[i][l-];prel=l,prer=r,opl=,opr=;kk-=r-l+;l=m+;r=m+;
  96. rp(p,prel,prer)printf("%lld %lld\n",i,p);continue;
  97. }
  98. }
  99. return ;
  100. }
  101. /*
  102. 0:递减
  103. 1:递增
  104. l:先0后1
  105. r:先1后0
  106. 0<-0/1 1<-1
  107. 1<-0/1 0<-0
  108. */

[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$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define gc getchar()
  5. #define t(i) edge[i].to
  6. #define ri register int
  7. #define rb register bool
  8. #define rc register char
  9. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  10. #define my(i,l,r) for(ri i=l;i>=r;--i)
  11. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  12.  
  13. const int N=+,M=5e3+;
  14. int n,m,g[N],f[N][M],sum[N],pre[N][M],as[N];
  15. struct nod{int g,id;}node[N];
  16.  
  17. il int read()
  18. {
  19. rc ch=gc;ri x=;rb y=;
  20. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  21. if(ch=='-')ch=gc,y=;
  22. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  23. return y?x:-x;
  24. }
  25. il bool cmp(nod gd,nod gs){return gd.g>gs.g;}
  26. il void work(ri n,ri m)
  27. {
  28. if(!n)return;
  29. if(pre[n][m]==n){work(pre[n][m],m-n);rp(i,,n)++as[node[i].id];return;}
  30. work(pre[n][m],m-(n-pre[n][m]));rp(i,pre[n][m]+,n)as[node[i].id]=;return;
  31. }
  32.  
  33. int main()
  34. {
  35. //freopen("5105.in","r",stdin);freopen("5105.out","w",stdout);
  36. n=read();m=read();rp(i,,n)node[i]=(nod){read(),i};sort(node+,node++n,cmp);rp(i,,n)sum[i]=sum[i-]+node[i].g;memset(f,,sizeof(f));f[][]=;
  37. rp(i,,n)
  38. rp(j,i,m)
  39. {
  40. f[i][j]=f[i][j-i];pre[i][j]=i;
  41. rp(k,,i-)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;
  42. }
  43. printf("%d\n",f[n][m]);
  44. work(n,m);
  45. rp(i,,n)printf("%d ",as[i]);
  46. return ;
  47. }

[X]数字组合

无脑$dp$,,,?

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

$over$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define gc getchar()
  5. #define t(i) edge[i].to
  6. #define ri register int
  7. #define rb register bool
  8. #define rc register char
  9. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  10. #define my(i,l,r) for(ri i=l;i>=r;--i)
  11. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  12.  
  13. const int N=+,M=+;
  14. int n,m,a[N],f[M];
  15.  
  16. il int read()
  17. {
  18. rc ch=gc;ri x=;rb y=;
  19. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  20. if(ch=='-')ch=gc,y=;
  21. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  22. return y?x:-x;
  23. }
  24.  
  25. int main()
  26. {
  27. //freopen("5201.in","r",stdin);freopen("5201.out","w",stdout);
  28. n=read();m=read();rp(i,,n)a[i]=read();f[]=;
  29. rp(i,,n)
  30. my(j,m,a[i])f[j]+=f[j-a[i]];
  31. printf("%d\n",f[m]);
  32. return ;
  33. }

背包板子我居然打了10$min$,,,是不是小水题做多了会影响智商昂$TT$

[X]自然数拆分

又是个无脑$dp$,,,

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

$over$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define int long long
  5. #define gc getchar()
  6. #define t(i) edge[i].to
  7. #define ri register int
  8. #define rb register bool
  9. #define rc register char
  10. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  11. #define my(i,l,r) for(ri i=l;i>=r;--i)
  12. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  13.  
  14. const int M=+,mod=;
  15. int n,f[M];
  16.  
  17. il int read()
  18. {
  19. rc ch=gc;ri x=;rb y=;
  20. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  21. if(ch=='-')ch=gc,y=;
  22. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  23. return y?x:-x;
  24. }
  25.  
  26. main()
  27. {
  28. //freopen("5202.in","r",stdin);freopen("5202.out","w",stdout);
  29. n=read();f[]=;
  30. rp(i,,n)rp(j,i,n)f[j]=(f[j]+f[j-i])%mod;
  31. printf("%lld\n",f[n]->=?f[n]-:mod-);
  32. return ;
  33. }

完全背包板子昂$QwQ$

[X]$Jury\ Compromise$

做过了,看这儿

[X]$Coins$

做过了,看这儿

[X]石子合并

无脑区间$dp$

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

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

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

$over$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,m,a[],f[][],f1[][],sum[],q=,ww,e,maxl=,minl=,i,j,l;
  4. int main()
  5. {
  6. cin>>n;
  7. for(i=;i<=n;i++)
  8. {
  9. cin>>a[i];
  10. a[i+n]=a[i];
  11. }
  12. for(i=;i<=*n;i++)sum[i]=sum[i-]+a[i];
  13. for(l=;l<=n;l++)
  14. {
  15. for(i=;i<=*n-l+;i++)
  16. {
  17. j=i+l-;
  18. f[i][j]=;
  19. f1[i][j]=;
  20. for(int k=i;k<=j-;k++)
  21. {
  22. f[i][j]=min(f[i][j],f[i][k]+f[k+][j]+sum[j]-sum[i-]);
  23. f1[i][j]=max(f1[i][j],f1[i][k]+f1[k+][j]+sum[j]-sum[i-]);
  24. }
  25. }
  26. }
  27. for(i=;i<=n;i++)
  28. {
  29. maxl=max(maxl,f1[i][i+n-]);
  30. minl=min(minl,f[i][i+n-]);
  31. }
  32. cout<<minl<<endl<<maxl;
  33. return ;
  34. }

[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$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define int long long
  5. #define gc getchar()
  6. #define t(i) edge[i].to
  7. #define ri register int
  8. #define rb register bool
  9. #define rc register char
  10. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  11. #define my(i,l,r) for(ri i=l;i>=r;--i)
  12. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  13.  
  14. const int N=+,mod=1e9;
  15. int n,f[N][N];
  16. char str[N];
  17.  
  18. il int read()
  19. {
  20. rc ch=gc;ri x=;rb y=;
  21. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  22. if(ch=='-')ch=gc,y=;
  23. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  24. return y?x:-x;
  25. }
  26. il int solve(ri l,ri r)
  27. {
  28. if(str[l]!=str[r])return ;if(l>r)return ;if(l==r)return ;if(f[l][r]!=-)return f[l][r];
  29. f[l][r]=;
  30. rp(i,l+,r-)if(str[l]==str[r])f[l][r]=(f[l][r]+1ll*solve(l+,i-)*solve(i,r)%mod)%mod;
  31. f[l][r]=(f[l][r]+solve(l+,r-))%mod;
  32. return f[l][r];
  33. }
  34.  
  35. main()
  36. {
  37. //freopen("5302.in","r",stdin);freopen("5302.out","w",stdout);
  38. scanf("%s",str+);n=strlen(str+);memset(f,-,sizeof(f));
  39. printf("%lld\n",solve(,n));
  40. return ;
  41. }

[X]没有上司的舞会

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

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

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

$over$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define gc getchar()
  5. #define t(i) edge[i].to
  6. #define ri register int
  7. #define rb register bool
  8. #define rc register char
  9. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  10. #define my(i,l,r) for(ri i=l;i>=r;--i)
  11. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  12.  
  13. const int N=+;
  14. int n,h[N],f[N][],head[N],ed_cnt,fa[N],rt;
  15. struct ed{int to,nxt;}edge[N];
  16.  
  17. il int read()
  18. {
  19. rc ch=gc;ri x=;rb y=;
  20. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  21. if(ch=='-')ch=gc,y=;
  22. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  23. return y?x:-x;
  24. }
  25. il void ad(ri to,ri fr){edge[++ed_cnt]=(ed){to,head[fr]};head[fr]=ed_cnt;fa[to]=fr;}
  26. il void solve(ri x){e(i,x)solve(t(i)),f[x][]+=max(f[t(i)][],f[t(i)][]),f[x][]+=f[t(i)][];f[x][]+=h[x];return;}
  27.  
  28. int main()
  29. {
  30. //freopen("5401.in","r",stdin);freopen("5401.out","w",stdout);
  31. n=read();rp(i,,n)h[i]=read();rp(i,,n){ri x=read(),y=read();ad(x,y);}
  32. rp(i,,n)if(!fa[i])rt=i;solve(rt);printf("%d\n",max(f[rt][],f[rt][]));
  33. return ;
  34. }

[X]选课

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

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

$over$

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

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

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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define gc getchar()
  5. #define t(i) edge[i].to
  6. #define ri register int
  7. #define rb register bool
  8. #define rc register char
  9. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  10. #define my(i,l,r) for(ri i=l;i>=r;--i)
  11. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  12.  
  13. const int N=+;
  14. int s[N],ed_cnt,head[N],n,m,f[N][N],as;
  15. bool vis[N][N][];
  16. struct ed{int to,nxt;}edge[N];
  17.  
  18. il int read()
  19. {
  20. rc ch=gc;ri x=;rb y=;
  21. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  22. if(ch=='-')ch=gc,y=;
  23. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  24. return y?x:-x;
  25. }
  26. il void ad(ri fr,ri to){edge[++ed_cnt]=(ed){to,head[fr]};head[fr]=ed_cnt;}
  27. il void solve(ri x){e(i,x){solve(t(i));my(j,m+,)rp(k,,j-)f[x][j]=max(f[x][j],f[t(i)][k]+f[x][j-k]);}}
  28.  
  29. int main()
  30. {
  31. freopen("2014.in","r",stdin);freopen("2014.out","w",stdout);
  32. n=read();m=read();
  33. rp(i,,n)ad(read(),i),f[i][]=read();
  34. solve();printf("%d\n",f[][m+]);
  35. return ;
  36. }

[ ]$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$,,,?

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define gc getchar()
  5. #define t(i) edge[i].to
  6. #define ri register int
  7. #define rb register bool
  8. #define rc register char
  9. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  10. #define my(i,l,r) for(ri i=l;i>=r;--i)
  11. #define e(i,x) for(ri i=head[x];i;i=edge[i].nxt)
  12.  
  13. const int N=1e6+;
  14. int n,a[N<<],que[N<<],head,tail,as;
  15.  
  16. il int read()
  17. {
  18. rc ch=gc;ri x=;rb y=;
  19. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  20. if(ch=='-')ch=gc,y=;
  21. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  22. return y?x:-x;
  23. }
  24. struct gdgs
  25. {
  26. int que[N<<],head,tail;
  27. gdgs(){head=,tail=;}
  28. il int top(){return a[que[head]]-que[head];}
  29. il void push(ri x){while(a[que[tail]]-que[tail]<=a[x]-x && tail>=head)--tail;que[++tail]=x;}
  30. il void clr(ri x){while(que[head]<x && tail>=head)++head;}
  31. }qwq;
  32.  
  33. int main()
  34. {
  35. //freopen("5501.in","r",stdin);freopen("5501.out","w",stdout);
  36. n=read();rp(i,,n)a[i]=a[i+n]=read();
  37. rp(i,,n<<)
  38. {
  39. qwq.clr(i-n/);
  40. if(i>=n)as=max(as,a[i]+i+qwq.top());qwq.push(i);
  41. }
  42. printf("%d\n",as);
  43. return ;
  44. }

[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?

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define lf double
  5. #define int long long
  6. #define gc getchar()
  7. #define mp make_pair
  8. #define ri register int
  9. #define rb register bool
  10. #define rc register char
  11. #define rp(i,x,y) for(ri i=x;i<=y;++i)
  12. #define my(i,x,y) for(ri i=x;i>=y;--i)
  13.  
  14. const int N=+,inf=1e9+;const lf eps=1e-;
  15. int n,h[N],f[N][][],la[N][][],lb[N][][],as1,as2,as;
  16. lf tmp_as;
  17.  
  18. il int read()
  19. {
  20. ri x=;rb y=;rc ch=gc;
  21. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  22. if(ch=='-')ch=gc,y=;
  23. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  24. return y?x:-x;
  25. }
  26. namespace gdgs
  27. {
  28. int rt,nod_cnt;
  29. struct node{int fa,ch[],val,cnt,sz,nam;il void pre(ri x,ri fat,ri name){ch[]=ch[]=;fa=fat;val=x;cnt=sz=;nam=name;}}tr[N];
  30. struct qwq{int nam,hei;}qaq[];
  31. il int abs(ri x){return x>?x:-x;}
  32. il bool cmp(qwq gd,qwq gs){return abs(gd.hei)==abs(gs.hei)?gd.hei<gs.hei:abs(gd.hei)<abs(gs.hei);}
  33. il void pushup(ri x){tr[x].sz=tr[tr[x].ch[]].sz+tr[tr[x].ch[]].sz+tr[x].cnt;}
  34. il void rotate(ri x)
  35. {
  36. ri fa=tr[x].fa,grdfa=tr[fa].fa;bool op1=tr[fa].ch[]==x,op2=tr[grdfa].ch[]==fa;
  37. tr[grdfa].ch[op2]=x;tr[x].fa=grdfa;
  38. tr[fa].ch[op1]=tr[x].ch[op1^];tr[tr[x].ch[op1^]].fa=fa;
  39. tr[fa].fa=x;tr[x].ch[op1^]=fa;
  40. pushup(fa);pushup(x);
  41. }
  42. il void splay(ri x,ri goal)
  43. {
  44. while(tr[x].fa!=goal)
  45. {
  46. ri fa=tr[x].fa,grdfa=tr[fa].fa;
  47. if(grdfa!=goal)(tr[fa].ch[]==x)^(tr[grdfa].ch[]==fa)?rotate(x):rotate(fa);
  48. rotate(x);
  49. }
  50. if(!goal)rt=x;
  51. }
  52. il void insert(ri x,ri nam)
  53. {
  54. ri nw=rt,fa=;
  55. while(nw && tr[nw].val!=x)fa=nw,nw=tr[nw].ch[x>tr[nw].val];
  56. nw=++nod_cnt;if(fa)tr[fa].ch[x>tr[fa].val]=nod_cnt;tr[nod_cnt].pre(x,fa,nam);
  57. splay(nw,);
  58. }
  59. 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,);}
  60. il int ask_pr(ri x){fd(x);ri nw=tr[rt].ch[];while(tr[nw].ch[])nw=tr[nw].ch[];return nw;}
  61. il int ask_nxt(ri x){fd(x);ri nw=tr[rt].ch[];while(tr[nw].ch[])nw=tr[nw].ch[];return nw;}
  62. il void pre_nxt()
  63. {
  64. insert(inf,);insert(inf+,);insert(-inf,);insert(-inf-,);f[n-][][]=n;lb[n-][][]=abs(h[n]-h[n-]);insert(h[n],n);insert(h[n-],n-);
  65. my(i,n-,)
  66. {
  67. insert(h[i],i);
  68. qaq[].nam=tr[ask_pr(h[i])].nam,qaq[].hei=h[qaq[].nam]-h[i];
  69. qaq[].nam=tr[ask_pr(h[qaq[].nam])].nam;qaq[].hei=h[qaq[].nam]-h[i];
  70. qaq[].nam=tr[ask_nxt(h[i])].nam,qaq[].hei=h[qaq[].nam]-h[i];
  71. qaq[].nam=tr[ask_nxt(h[qaq[].nam])].nam;qaq[].hei=h[qaq[].nam]-h[i];
  72. sort(qaq+,qaq++,cmp);
  73. f[i][][]=qaq[].nam;f[i][][]=qaq[].nam;lb[i][][]=abs(qaq[].hei);la[i][][]=abs(qaq[].hei);
  74. }
  75. }
  76. }
  77. il void pre()
  78. {
  79. rp(i,,n)
  80. {
  81. f[i][][]=f[f[i][][]][][];f[i][][]=f[f[i][][]][][];
  82. if(f[i][][])la[i][][]=la[i][][],la[i][][]=lb[f[i][][]][][];
  83. if(f[i][][])lb[i][][]=lb[i][][],lb[i][][]=la[f[i][][]][][];
  84. }
  85. for(ri j=;((<<j)|)<=n;++j)
  86. rp(i,,n-(<<j))
  87. {
  88. f[i][j][]=f[f[i][j-][]][j-][];f[i][j][]=f[f[i][j-][]][j-][];
  89. if(f[i][j][])la[i][j][]=la[i][j-][]+la[f[i][j-][]][j-][],la[i][j][]=la[i][j-][]+la[f[i][j-][]][j-][];
  90. if(f[i][j][])lb[i][j][]=lb[i][j-][]+lb[f[i][j-][]][j-][],lb[i][j][]=lb[i][j-][]+lb[f[i][j-][]][j-][];
  91. }
  92. }
  93. il void query(ri x,ri dis,ri &as1,ri &as2,rb y)
  94. {
  95. //printf("x=%d dis=%d as1=%d as2=%d y=%d\n",x,dis,as1,as2,y);
  96. if(!y)
  97. {
  98. my(i,,)
  99. if(f[x][i][] && la[x][i][]+la[x][i][]<=dis)
  100. {dis-=la[x][i][]+la[x][i][];as1+=la[x][i][];as2+=la[x][i][];/*printf(" i=%d\n",i);*/query(f[x][i][],dis,as1,as2,y^(i==));return;}
  101. }
  102. else
  103. {
  104. my(i,,)
  105. if(f[x][i][] && lb[x][i][]+lb[x][i][]<=dis)
  106. {dis-=lb[x][i][]+lb[x][i][];as1+=lb[x][i][];as2+=lb[x][i][];/*printf(" i=%d\n",i);*/query(f[x][i][],dis,as1,as2,y^(i==));return;}
  107. }
  108. }
  109.  
  110. main()
  111. {
  112. //freopen("1081.in","r",stdin);freopen("1081.out","w",stdout);
  113. n=read();rp(i,,n)h[i]=read();h[]=inf;gdgs::pre_nxt();pre();
  114. //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]);
  115. /*预处理麻油问题!yep!*/
  116. ri x=read();tmp_as=inf;
  117. rp(i,,n)
  118. {
  119. ri as1=,as2=;lf tmp;query(i,x,as1,as2,);
  120. //printf("i=%d as1=%d as2=%d\n",i,as1,as2);
  121. if(!as2)continue;
  122. tmp=(lf)as1/as2;
  123. if(tmp_as>tmp)tmp_as=tmp,as=i;
  124. else if(abs(tmp_as-tmp)<=eps && h[i]>h[as])as=i;
  125. }
  126. printf("%lld\n",as);
  127. ri m=read();
  128. while(m--){ri s=read(),x=read(),as1=,as2=;query(s,x,as1,as2,);printf("%lld %lld\n",as1,as2);}
  129. return ;
  130. }

[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$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define int long long
  5. #define lf double
  6. #define gc getchar()
  7. #define ri register int
  8. #define rb register bool
  9. #define rc register char
  10. #define rp(i,x,y) for(ri i=x;i<=y;++i)
  11. #define my(i,x,y) for(ri i=x;i>=y;--i)
  12.  
  13. const int N=+;
  14. int n,f[N][],tot_len,len1,len2,m;
  15. char s1[N],s2[N];
  16.  
  17. il int read()
  18. {
  19. ri x=;rb y=;rc ch=gc;
  20. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  21. if(ch=='-')ch=gc,y=;
  22. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  23. return y?x:-x;
  24. }
  25. il bool pre()
  26. {
  27. rp(i,,len1-)
  28. {ri pos=i;rp(j,,len2-){ri cnt=;while(s1[pos]!=s2[j]){++pos;pos%=len1;++cnt;if(cnt>len1)return printf("0\n"),;}++pos;pos%=len1;f[i][]+=cnt+;}}
  29. rp(j,,)rp(i,,len1-)f[i][j]=f[i][j-]+f[(i+f[i][j-])%len1][j-];
  30. return ;
  31. }
  32.  
  33. main()
  34. {
  35. while(~scanf("%s",s2))
  36. {
  37. memset(f,,sizeof(f));
  38. ri n2=read();scanf("%s",s1);n=read();len1=strlen(s1);len2=strlen(s2);tot_len=len1*n;m=;
  39. if(!pre())continue;ri pos=;my(i,,)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+=<<i,pos+=f[pos][i],pos%=len1;}
  40. printf("%lld\n",m/n2);
  41. }
  42. return ;
  43. }

[ ]$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}$的范围挺大的,记得离散化昂

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define il inline
  4. #define int long long
  5. #define lf double
  6. #define gc getchar()
  7. #define ri register int
  8. #define rb register bool
  9. #define rc register char
  10. #define rp(i,x,y) for(ri i=x;i<=y;++i)
  11. #define my(i,x,y) for(ri i=x;i>=y;--i)
  12. #define lowbit(x) (x&(-x))
  13. #define lb(x) lower_bound(st+1,st+1+st_cnt,x)-st
  14.  
  15. const int N=+,mod=1e9+;
  16. int n,m,a[N],f[N][N],st[N],st_cnt,cnt,tr[N];
  17.  
  18. il int read()
  19. {
  20. ri x=;rb y=;rc ch=gc;
  21. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  22. if(ch=='-')ch=gc,y=;
  23. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  24. return y?x:-x;
  25. }
  26. il void ad(ri x,ri dat){while(x<=st_cnt)tr[x]=(tr[x]+dat)%mod,x+=lowbit(x);}
  27. il int query(ri x){ri ret=;while(x){ret=(ret+tr[x])%mod;x-=lowbit(x);}return ret;}
  28.  
  29. main()
  30. {
  31. ri T=read();
  32. while(T--)
  33. {
  34. printf("Case #%lld: ",++cnt);memset(f,,sizeof(f));
  35. n=read();m=read();rp(i,,n)a[i]=st[i]=read();sort(st+,st++n);st_cnt=unique(st+,st++n)-st-;rp(i,,n)a[i]=lb(a[i]),f[i][]=;
  36. rp(j,,m){memset(tr,,sizeof(tr));rp(i,,n)f[i][j]=query(a[i]-),ad(a[i],f[i][j-]);}
  37. ri as=;rp(i,,n)as=(as+f[i][m])%mod;printf("%lld\n",as);
  38. }
  39. return ;
  40. }

[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$

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,m,s[],c[],dp[][][][];
  4. bool o;
  5. int main()
  6. {
  7. scanf("%d%d",&n,&m);
  8. for(int i=;i<=n;i++)cin>>s[i];
  9. for(int i=;i<=m;i++)
  10. {
  11. int t;
  12. cin>>t;
  13. c[t]++;
  14. }
  15. dp[][][][]=s[];
  16. for(int i=;i<=c[];i++)
  17. for(int j=;j<=c[];j++)
  18. for(int k=;k<=c[];k++)
  19. for(int p=;p<=c[];p++)
  20. {
  21. if(i>)dp[i][j][k][p]=max(dp[i-][j][k][p]+s[i+j*+k*+p*+],dp[i][j][k][p]);
  22. if(j>)dp[i][j][k][p]=max(dp[i][j-][k][p]+s[i+j*+k*+p*+],dp[i][j][k][p]);
  23. if(k>)dp[i][j][k][p]=max(dp[i][j][k-][p]+s[i+j*+k*+p*+],dp[i][j][k][p]);
  24. if(p>)dp[i][j][k][p]=max(dp[i][j][k][p-]+s[i+j*+k*+p*+],dp[i][j][k][p]);
  25. // cout<<"i="<<i<<" j="<<j<<" k="<<k<<" p="<<p<<" dp="<<dp[i][j][k][p]<<endl;
  26. }
  27. cout<<dp[c[]][c[]][c[]][c[]];
  28. return ;
  29. }

[X]花店橱窗

无脑$dp$

甚至连题解都不想写

直接看$code$趴,,,

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. long long a[],n,i,j,k,ans[][],maxans;
  4. int main()
  5. {
  6. cin>>n;
  7. for(i=;i<=n;i++)
  8. {
  9. cin>>a[i];
  10. a[i+n]=a[i];
  11. }
  12. for(i=;i<*n;i++)
  13. for(j=i-;j>= && i-j<n;j--)
  14. {
  15. for(k=j;k<i;k++)
  16. ans[j][i]=max(ans[j][i],ans[j][k]+ans[k+][i]+a[i+]*a[k+]*a[j]);
  17. maxans=max(maxans,ans[j][i]);
  18. }
  19. cout<<maxans;
  20. return ;
  21. }

[ ]$Buy\ Low\ Buy\ Lower$

[ ]$Trip$

[ ]$Substract$

[ ]陨石的秘密

[ ]划分大理石

[ ]$Folding$

[X]能量项链

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

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

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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. long long a[],n,i,j,k,ans[][],maxans;
  4. int main()
  5. {
  6. cin>>n;
  7. for(i=;i<=n;i++)
  8. {
  9. cin>>a[i];
  10. a[i+n]=a[i];
  11. }
  12. for(i=;i<*n;i++)
  13. for(j=i-;j>= && i-j<n;j--)
  14. {
  15. for(k=j;k<i;k++)
  16. ans[j][i]=max(ans[j][i],ans[j][k]+ans[k+][i]+a[i+]*a[k+]*a[j]);
  17. maxans=max(maxans,ans[j][i]);
  18. }
  19. cout<<maxans;
  20. return ;
  21. }

[ ]棋盘分割

[X]$Blocks$

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

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

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

  1. #include<algorithm>
  2. #include<iomanip>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<cstdio>
  6. #include<string>
  7. using namespace std;
  8. #define il inline
  9. #define gc getchar()
  10. #define ri register int
  11. #define rb register bool
  12. #define rc register char
  13. #define rp(i,l,r) for(ri i=l;i<=r;++i)
  14. #define my(i,l,r) for(ri i=l;i>=r;--i)
  15.  
  16. const int N=;
  17. int n,color[N],cnt[N],f[N][N][N],now,ct,ans;
  18.  
  19. il int read()
  20. {
  21. rc ch=gc;ri x=;rb y=;
  22. while(ch!='-' && (ch>'' || ch<''))ch=gc;
  23. if(ch=='-')ch=gc,y=;
  24. while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
  25. return y?x:-x;
  26. }
  27. int bfs(int l,int r,int k)
  28. {
  29. if(f[l][r][k]!=)return f[l][r][k];if(l>r)return ;
  30. f[l][r][k]=bfs(l,r-,)+(cnt[r]+k)*(cnt[r]+k);
  31. rp(i,l,r-)if(color[i]==color[r])f[l][r][k]=max(bfs(l,i,cnt[r]+k)+bfs(i+,r-,),f[l][r][k]);
  32. return f[l][r][k];
  33. }
  34.  
  35. int main()
  36. {
  37. // freopen("QAQ.in","r",stdin);freopen("QAQ.out","w",stdout);
  38. ri T=read();
  39. rp(i,,T)
  40. {
  41. memset(color,,sizeof(color));memset(f,,sizeof(f));now=;n=read();
  42. rp(j,,n){ct=read();if(ct==color[now])++cnt[now];else{++now;cnt[now]=;color[now]=ct;}}
  43. ans=bfs(,now,);
  44. cout<<"Case "<<i<<": "<<ans<<endl;
  45. }
  46. return ;
  47. }

[ ]$Strategic\ game$

[ ]$Bugs\ Integrated\ Inc$

[ ]$Fence\ Obstacle\ Course$

[ ]$K-Anonymous\ Sequence$

[ ]$Post\ Office$

[ ]扑克牌

[ ]$The\ Counting\ Problem$

随机推荐

  1. windows 和 linux 安装 tensorflow

    安装 跟往常一样,我们用 Conda 来安装 TensorFlow.你也许已经有了一个 TensorFlow 环境,但要确保你安装了所有必要的包. OS X 或 Linux 运行下列命令来配置开发环境 ...

  2. 08查找满足条件的n个数

    第一节.寻找和为定值的两个数 题目:输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出任意一对即可. 例如输 ...

  3. 解决bootStrap selectpicker 下拉栏上方弹出

    最近项目中遇到了一个使用bootStrap selectpicker 进行下拉栏展示的时候出现在元素上方弹出展示的问题,可把我难受坏了,和测试互怼最终以失败告终(人家还是一个娇滴滴的小姑娘),在查了a ...

  4. ODT 珂朵莉树 入门

    #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> ...

  5. 首次揭秘:阿里巴巴中间件在 Serverless 技术领域的探索

    Serverless 话题涉及范围极广,几乎包含了代码管理.测试.发布.运维和扩容等与应用生命周期关联的所有环节.AWS Lambda 是 Serverless 领域的标志性产品,但如果将其应用于核心 ...

  6. js常见运算符

    博客地址 :https://www.cnblogs.com/sandraryan/

  7. 【转载】.NET中使用Redis

    Redis是一个用的比较广泛的Key/Value的内存数据库,新浪微博.Github.StackOverflow 等大型应用中都用其作为缓存,Redis的官网为http://redis.io/. 最近 ...

  8. 洛谷P5020 货币系统 题解 模拟

    题目链接:https://www.luogu.org/problem/P5020 这道题目是一道模拟题,但是又有一点多重背包的思想在里面. 首先我们定义一个 vis[i] 来表示和为 i 的情况在之前 ...

  9. 智课雅思词汇---九、mon是什么意思

    智课雅思词汇---九.mon是什么意思 一.总结 一句话总结:词根:mon(min) = to warn, to advise, to remind 1.mit是什么意思? 词根:-mitt-, -m ...

  10. linux下C调用lua的第一个程序

    linux下C调用lua的第一个程序 linux的环境是Fedora 18,运行在VM workstation中,以开发模式安装,自带了lua 5.1.4,可以在命令行上直接用lua命令进入到lua环 ...