zoukankan      html  css  js  c++  java
  • [USACO13NOV]No Change

    题目大意:
      你有k(k<=16)个硬币,每个硬币都有自己的面值。
      现在你要给n件商品付钱,每件商品也有自己的价格。
      然而老板是个奸商,他绝对不会给你找钱。
      你每次付钱只能用一个硬币,但是你可以一次性买很多商品。
      问你最后最多还能留下多少钱。

    思路:
      状压DP。
      f[i]表示状态为i时能买的商品数,i表示你用了哪些硬币。
      从小到大枚举每个状态i,然后枚举状态i中的硬币j,是这次付款用的硬币。
      二分找一下这些硬币最多能买前面连续的多少个商品。
      如果j不在i中,就算作最后剩下的硬币。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 const int K=16,N=100001;
    12 int v[K],sum[N],f[1<<K];
    13 int main() {
    14     const int k=getint(),n=getint();
    15     for(register int i=0;i<k;i++) {
    16         v[i]=getint();
    17     }
    18     for(register int i=1;i<=n;i++) {
    19         sum[i]=sum[i-1]+getint();
    20     }
    21     int ans=-1;
    22     for(register int i=0;i<(1<<k);i++) {
    23         int rem=0;
    24         for(register int j=0;j<k;j++) {
    25             if(i&(1<<j)) {
    26                 f[i]=std::max(f[i],int(std::upper_bound(&sum[0],&sum[n+1],sum[f[i^(1<<j)]]+v[j])-sum-1));
    27             } else {
    28                 rem+=v[j];
    29             }
    30         }
    31         if(f[i]==n) {
    32             ans=std::max(ans,rem);
    33         }
    34     }
    35     printf("%d
    ",ans);
    36     return 0;
    37 }
  • 相关阅读:
    [原]鼠标移至小图,自动显示相应大图
    [整理]asp.net导出Excel/Csv格式数据方案
    [整理]asp.net 上传大文件解决方案
    唐伯虎诗词
    [转]浅析软件项目管理中的10个误区
    [推荐]让SQL跑得更快
    [原]ASP.Net常用功能整理生成图片的缩略图
    [推荐]数据库性能优化
    SQL优化原则
    天地男儿
  • 原文地址:https://www.cnblogs.com/skylee03/p/7743480.html
Copyright © 2011-2022 走看看