2018.8.23 练习赛

  • T1 三级包
  • 题意:带数量限制的0/1背包问题,但是容量极大,没办法dp。
  • 正解是分为两部分状态压缩;但是实际上暴搜加上卡时(100000000)就能过
  •  1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<ctype.h>
     6 using namespace std;
     7 int f[50][50];
     8 int n,m,k,w[50],ans,tot;
     9 
    10 template<typename T>
    11 void read(T &x) {
    12     char tt;
    13     bool flag=0;
    14     while(!isdigit(tt=getchar())&&tt!='-');
    15     tt=='-'?(x=0,flag=1):(x=tt-'0');
    16     while(isdigit(tt=getchar())) x=x*10+tt-'0';
    17 }
    18 
    19 
    20 void dfs(int num,int now,int x) {
    21     ++tot;
    22     ans=max(ans,x);
    23     if(tot>100000000) return;
    24     if(now>k) return;
    25     if(num+1<=n&&x+w[now]<=m) dfs(num+1,now+1,x+w[now]);
    26     dfs(num,now+1,x);
    27 }
    28 int cmp(int a,int b) {
    29     return a>b;
    30 }
    31 int main() {
    32     read(n),read(m);
    33     read(k);
    34     for(int i=1; i<=k; i++) read(w[i]);
    35     sort(w+1,w+k+1,cmp);
    36     int s=0;
    37     for(int i=1; i<=n; i++) s+=w[i];
    38     if(s<=m) printf("%d\n",s),exit(0);
    39     dfs(0,1,0);
    40     printf("%d\n",ans);
    41 }
    View Code

     

  • T2 三级甲
  • 题意:求给定数列中,所有区间长度为k的最小值之和
  • 通过预处理a[I]的贡献计算每次询问
  • 代码:待补
  • T3 三级头
  • 题意:给定一棵树,完成三种操作:1.查询点x子树中严格大于y的点个数;2,指定点x为根;3.修改点x的值为y
  • 分块,维护块中有序,每次询问二分查找,更新用插入排序,更新的复杂度为,写起来有点毒瘤……
  • 代码:待补
posted @ 2018-08-23 20:21  Katoumegumi  阅读(63)  评论(0编辑  收藏  举报
返回顶部