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 }
  • 相关阅读:
    mysql:添加索引
    mysql: update字段中带select
    ASP.NET Web API 2 入门
    notify()、notifyAll()和wait()
    Mybatis3 框架理解
    项目中用到的Java注解
    使用webservice实现App与服务器端数据交互
    IntelliJ idea 14 集成 tomcat 7
    使用adb签名并安装Android程序
    写了一个月的单元测试,总算明白大学里这门课白学了
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10390719.html
Copyright © 2011-2022 走看看