• UVA


    题目链接

    题目大意:有S门课程,N名在职教师和M名求职者,每名在职教师或求职者都有自己能教的课程集合以及工资,要求花费尽量少的钱选择一些人,使得每门课程都有至少两人教。在职教师必须选。

    可以把“每个课程已经分别有几个人教”作为状态来进行转移,每个人能教的课程集合作为“物品重量”,工资作为“价值”来更新dp值,类似01背包,每放进一个人,从后往前更新即可。

    状态的表示可以用三进制编码,为了写起来舒服,我写了个结构体作为状态和编码转换的桥梁,也可以进行状态的“加法运算”,虽然速度比较慢就是了~~

    有点想吐槽的是,出题人就不能把每个人能教的课程数量也放在输入里么?非逼得人家用getline嘛~~

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll N=8+2,inf=0x3f3f3f3f;
     5 int k,n,m,d[(1<<(N*2))+10],co,mx;
     6 string line;
     7 struct D {
     8     int a[N];
     9     int& operator[](int x) {return a[x];}
    10     D(int x=0) {
    11         memset(a,0,sizeof a);
    12         for(int i=0; i<k; ++i,x/=3)a[i]=x%3;
    13     }
    14     D operator+(D& b) {
    15         D ret;
    16         for(int i=0; i<k; ++i)ret[i]=min(a[i]+b[i],2);
    17         return ret;
    18     }
    19     operator int() {
    20         int ret=0;
    21         for(int i=k-1; i>=0; --i)ret=ret*3+a[i];
    22         return ret;
    23     }
    24 
    25 };
    26 
    27 int main() {
    28     ios::sync_with_stdio(0);
    29     while(cin>>k>>n>>m&&k) {
    30         cin.ignore();
    31         memset(d,inf,sizeof d);
    32         d[0]=0;
    33         co=0,mx=pow(3,k)+0.5;
    34         while(n--) {
    35             getline(cin,line);
    36             stringstream ss(line);
    37             int x;
    38             ss>>x;
    39             co+=x;
    40             D t;
    41             while(ss>>x)t[x-1]=1;
    42             for(int i=mx-1; i>=0; --i)if(!d[i])d[D(i)+t]=0;
    43         }
    44         for(int i=0; i<mx; ++i)if(!d[i])d[i]=co;
    45         while(m--) {
    46             getline(cin,line);
    47             stringstream ss(line);
    48             ss>>co;
    49             int x;
    50             D t;
    51             while(ss>>x)t[x-1]=1;
    52             for(int i=mx-1; i>=0; --i) {
    53                 d[D(i)+t]=min(d[D(i)+t],d[i]+co);
    54             }
    55         }
    56         printf("%d
    ",d[mx-1]);
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    详细分析MySQL事务日志(redo log和undo log)
    详细分析MySQL的日志(一)
    MySQL/MariaDB中的事务和事务隔离级别
    详细介绍MySQL/MariaDB的锁
    MariaDB/MySQL用户和权限管理
    (MariaDB)开窗函数用法
    翻译:window function(已提交到MariaDB官方手册)
    翻译:group_concat()函数(已提交到MariaDB官方手册)
    (MariaDB/MySQL)之DML(1):数据插入
    (MariaDB/MySQL)MyISAM存储引擎读、写操作的优先级
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10380979.html
Copyright © 2020-2023  润新知