zoukankan      html  css  js  c++  java
  • UVA

    题意:给你一些邮票面值的集合,让你选择其中一个集合,使得“能用不超过n枚集合中的邮票凑成的面值集合S中从1开始的最大连续面值”(即mex(S)-1)最大。如果有多解,输出集合大小最小的一个;如果仍有多解,输出面值从大到小排序后最小的一个。

    少数能用bitset优化的dp问题之一。设bs[i]为用不超过i枚邮票能凑成的面值集合,正在放进的邮票面值为j,则有状态更新公式:$bs[i+1]=bs[i]|(bs[i]<<j)$,根据这个公式进行转移即可。

    保存答案可以用vector,便于长度以及字典序的比较。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=20+5,M=10+2,inf=0x3f3f3f3f;
     5 int n,m,k,ans;
     6 vector<int> v1,v2;
     7 bitset<1000+10> bs[M];
     8 
     9 bool cmp(vector<int>& v1,vector<int>& v2) {
    10     if(v1.size()!=v2.size())return v1.size()<v2.size();
    11     for(int i=v1.size()-1; i>=0; --i)if(v1[i]!=v2[i])return v1[i]<v2[i];
    12     return 0;
    13 }
    14 
    15 int main() {
    16     while(scanf("%d%d",&n,&m)&&n) {
    17         v1.clear(),v2.clear(),ans=0;
    18         while(m--) {
    19             for(int i=0; i<M; ++i)bs[i].reset();
    20             bs[0].set(0),v2.clear();
    21             scanf("%d",&k);
    22             while(k--) {
    23                 int x;
    24                 scanf("%d",&x);
    25                 for(int i=0; i<n; ++i)bs[i+1]|=bs[i]|(bs[i]<<x);
    26                 v2.push_back(x);
    27             }
    28             for(int i=0;; ++i)if(!bs[n].test(i)) {
    29                     if(i>ans||(i==ans&&cmp(v2,v1)))ans=i,v1=v2;
    30                     break;
    31                 }
    32         }
    33         printf("max coverage = %3d :",ans-1);
    34         for(int i:v1)printf("%3d",i);
    35         printf("
    ");
    36     }
    37     return 0;
    38 }
  • 相关阅读:
    简单区分Vmware的三种网络连接模式(bridged、NAT、host-only)
    linux创建账户并自动生成主目录和主目录下的文件
    EF 通用数据层类
    html在线美化网站
    图片在页面中居中显示
    __dopostback的用法
    rdlc报表集锦
    .NET开源免费的功能强大控件库
    使用webclient上传下载实例
    消息队列将并发变串行
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10390719.html
Copyright © 2011-2022 走看看