• USACO Section2.3 Money Systems 解题报告 【icedream61】


        money解题报告
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【题目】
      你有V种硬币,每种硬币面值都告诉你。
      请问,用它们凑出面值N,总共有多少种情况?
    【数据范围】
      1<=V<=25
      1<=N<=10000
      数据保证,总情况数不超过long long。
    【输入格式】
      第一行给出V和N。
      后面给出所有V种面值。
    【输入样例】
      3 10
      1 2 5
    【输出样例】
      10
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【分析】
      完全背包问题。
      之前写过背包问题的总结,不懂的同学可以去看我之前的博文:“背包问题基本解法 —— 《背包九讲》笔记”。
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【总结】
      开始对这题的数据范围并没有什么认识,于是枚举过了前7个点,第8个点超时。
      自己调试了下,发现整数拆分竟然有如此多种情况。于是换用神奇的背包做了。

    ------------------------------------------------------------------------------------------------------------------------------------------------

    【代码(注意,本题给出了两个版本的代码:背包算法和枚举法。)

    AC版本,即背包算法。

     1 /*
     2 ID: icedrea1
     3 PROB: money
     4 LANG: C++
     5 */
     6 
     7 #include <iostream>
     8 #include <fstream>
     9 using namespace std;
    10 
    11 const int maxv = 1+25;
    12 const int maxn = 1+10000;
    13 bool b[maxn];
    14 int d[maxv];
    15 
    16 int c[maxv];
    17 long long cnt[maxn];
    18 
    19 int main()
    20 {
    21     ifstream in("money.in");
    22     ofstream out("money.out");
    23 
    24     int V,N; in>>V>>N;
    25     for(int i=1,x;i<=V;++i) { in>>x; if(x<=N) b[x]=true; }
    26     V=0;
    27     for(int i=1;i<=N;++i)
    28         if(b[i]) d[++V]=i; // 保证输入硬币是从小到大的
    29 
    30     cnt[0]=1;
    31     for(int i=1;i<=V;++i)
    32         for(int j=d[i];j<=N;++j) cnt[j]+=cnt[j-d[i]];
    33 
    34     out<<cnt[N]<<endl;
    35 
    36     in.close();
    37     out.close();
    38     return 0;
    39 }

    只过7个点的版本,即枚举法。

     1 /*
     2 ID: icedrea1
     3 PROB: money
     4 LANG: C++
     5 */
     6 
     7 #include <iostream>
     8 #include <fstream>
     9 using namespace std;
    10 
    11 const int maxv = 1+25;
    12 const int maxn = 1+10000;
    13 bool b[maxn];
    14 int d[maxv];
    15 
    16 int c[maxv];
    17 long long ts;
    18 
    19 long long count(int n,int v) // 还剩n元,要决定d[v]的个数
    20 {
    21     //cout<<n<<' '<<v<<endl; //cin.get();
    22     ++ts; //if(ts%100000000==0) cout<<ts<<endl;
    23     if(n==0) return 1;
    24     if(v==0) return 0;
    25     long long s=0;
    26     for(int i=0;d[v]*i<=n;++i)
    27     {
    28         c[v]=i; s+=count(n-d[v]*i,v-1);
    29     }
    30     return s;
    31 }
    32 
    33 int main()
    34 {
    35     ifstream in("money.in");
    36     ofstream out("money.out");
    37 
    38     int V,N; in>>V>>N;
    39     for(int i=1,x;i<=V;++i) { in>>x; if(x<=N) b[x]=true; }
    40     V=0;
    41     for(int i=1;i<=N;++i)
    42         if(b[i]) d[++V]=i; // 保证输入硬币是从小到大的
    43 
    44     cout<<count(N,V)<<endl;
    45     cout<<"ts="<<ts<<endl;
    46 
    47     in.close();
    48     out.close();
    49     return 0;
    50 }
  • 相关阅读:
    CyclicBarrier与CountDownLatch区别
    导入搜狗实验室新闻语料库
    安装ik分词插件
    分页显示时传递页码的方法
    elasticsearch安装步骤
    linux查看端口占用情况
    Python:文件的读取、创建、追加、删除、清空
    R语言-选择样本数量
    不符合正态分布的配对数据也有自己的统计方法。
    python时间处理
  • 原文地址:https://www.cnblogs.com/icedream61/p/4524737.html
Copyright © 2020-2023  润新知