zoukankan      html  css  js  c++  java
  • SDU暑期集训排位(6)题解

    L - Olympiad Training

    $FWT$。首先,观察到$n$很小,我们可以想办法求出每个子集的答案,但是$m$很大,直接枚举子集的方法肯定行不通。不妨考虑对每个$topic$单独考虑贡献,设当前考虑的是第$j$个$topic$,然后枚举最大值,设$a_{ij}$为最大值,其他的人我们只能选比它小的,设我们能选出的最大的集合为$mask$,显然,对于$mask$子集$s$,如果$s$包含第$i$个人,答案就需要加上$a_{ij}$,如果不包含,它的最大值就为其他值,我们不妨分两步完成这个操作,首先,对于$mask$的所有子集加上答案$a_{ij}$,然后,设$mask'$为$mask$去掉$i$之后的集合,我们对$mask'$的所有子集减去$a_{ij}$,到此为止,如果我们能快速完成给子集同时加上一个数这个操作,这个题就做完了,$and$运算的$FWT$支持此操作。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 #include<algorithm>
     5 const int N=22;
     6 int n,q,m;
     7 typedef long long ll;
     8 ll f[1<<20],ans[22];
     9 typedef std::pair<int,int> P;
    10 std::vector<P> g[10004];
    11 void FWT(ll *a,int n) {
    12     for(int i=1;i<n;i<<=1)
    13         for(int p=i<<1,j=0;j<n;j+=p)
    14             for(int k=0;k<i;k++)
    15                 a[j+k]+=a[i+j+k];
    16 }
    17 int main() {
    18     int T;
    19     scanf("%d",&T);
    20     while(T--) {
    21         scanf("%d%d%d",&n,&m,&q);
    22         for(int i=0;i<1<<n;i++) f[i]=0;
    23         for(int i=0;i<m;i++) g[i].clear();
    24         for(int i=0;i<n;i++) {
    25             for(int j=0,x;j<m;j++) {
    26                 scanf("%d",&x);
    27                 g[j].push_back(P(x,i));
    28             }
    29         }
    30         for(int i=0;i<m;i++) {
    31             std::sort(g[i].begin(),g[i].end());
    32             int mask=0;
    33             for(P c:g[i]) {
    34                 mask|=1<<c.second;
    35                 f[mask]+=c.first;
    36                 f[mask^(1<<c.second)]-=c.first;
    37             }
    38         }
    39         FWT(f,1<<n);
    40         for(int i=1;i<=n;i++) ans[i]=1e18;
    41         for(int i=1;i<1<<n;i++) {
    42             int k=0;
    43             for(int j=0;j<n;j++) if(i>>j&1) ++k;
    44             ans[k]=std::min(ans[k],f[i]);
    45         }
    46         for(int k;q--;) {
    47             scanf("%d",&k);
    48             printf("%lld
    ",ans[k]);
    49         }
    50     }
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    Wpf 简单制作自己的窗体样式(2)
    Wpf 简单制作自己的窗体样式
    Microsoft Expression Blend 4制作简单的按钮
    Jest和enzyme 前端单元测试工具
    使用socket.io实现多房间通信聊天室
    如何快速开发一个微信小游戏--实例《打气球》
    使用flow来规范javascript的变量类型
    前端开发工具icestar
    vue.js和vue-router和vuex快速上手知识
    react.js插件开发,x-dailog弹窗浮层组件
  • 原文地址:https://www.cnblogs.com/Onlymyheart/p/11366406.html
Copyright © 2011-2022 走看看