zoukankan      html  css  js  c++  java
  • USACO Section2.1 Healthy Holsteins 解题报告 【icedream61】

        holstein解题报告

    ------------------------------------------------------------------------------------------------------------------------------------------------
    【题目】
      你需要给一头奶牛制定最优的喂养计划。
      有V种维他命,每天对于每种维他命,牛都有需要达到的指标;
      同时你有G种饲料,编号依次为1到G,每种维他命在每种饲料中所蕴含的量都会给你。
      请你从中选出N种饲料,在达到指标的前提下让N最小。
    【数据范围】
      1<=V<=25
      1<=每种维他命的指标<=1000
      1<=G<=15
    【输入格式】
      第一行是V,后面V行依次给出1号到V号维他命的指标;
      下面一行是G,后面G行依次是G种饲料,每行V个数,分别代表本饲料中各种维他命的含量。
    【输出格式】
      仅一行,各数用空格隔开。
      第一个数是所需的饲料种数N,后面N个数依次是所选饲料的编号。
      注意,若有多种方案N相同,则仅输出字典序最小的一组方案。
    【输入样例】
      4
      100 200 300 400
      3
      50 50 50 50
      200 300 200 300
      900 150 389 399
    【输出样例】
      2 1 3
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【分析】
      这题做法是枚举。
      V种维他命,G份饲料,不妨考虑最大值G=15、V=25。每种饲料枚举取or不取,大约是300,000种情况;每种情况分别用来更新当前最优解,耗时大约不到400。如此可见,本题枚举时间大约在120,000,000,而枚举法常数很小,故而完全可以在1s内完成。
    ------------------------------------------------------------------------------------------------------------------------------------------------
    【总结】
      第二次提交AC。第一次犯了点细节错误,把G和V有点弄混的地方。
    【吐槽】
      这题我严重被自己坑了。。
      一开始根本没往枚举法上想,觉得USACO Section2.1的题,怎么也应该有道难题了。。结果想了好长时间没想出做法来,然后一看——这G只有15!这不是完全可以枚举吗……

    【再次吐槽】

      博文竟然有重名。。今后解题报告标题后面都加上我id,我就不行还有重名-.-

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

    【代码】

     1 /*
     2 ID: icedrea1
     3 PROB: holstein
     4 LANG: C++
     5 */
     6 
     7 #include <iostream>
     8 #include <fstream>
     9 using namespace std;
    10 
    11 int V,G;
    12 int v[1+25],g[1+15][1+25];
    13 bool now[1+15];
    14 
    15 int r,s[1+25];
    16 bool good[1+15];
    17 
    18 bool better()
    19 {
    20     for(int k=1;k<=G;++k)
    21     {
    22         if(now[k] && !good[k]) return true;
    23         if(!now[k] && good[k]) return false;
    24     }
    25 }
    26 void Try()
    27 {
    28     int cnt=0,sum[1+25]={};
    29     for(int k=1;k<=G;++k)
    30         if(now[k])
    31         {
    32             ++cnt;
    33             for(int i=1;i<=V;++i) sum[i]+=g[k][i];
    34         }
    35     for(int i=1;i<=V;++i)
    36         if(sum[i]<v[i]) return; // 失败
    37     if(cnt<r || cnt==r && better())
    38     {
    39         r=cnt;
    40         for(int k=1;k<=G;++k) good[k]=now[k];
    41     }
    42 }
    43 
    44 void go(int k) //前k组要不要已定
    45 {
    46     if(k==G) { Try(); return; }
    47     ++k; go(k);
    48     now[k]=true; go(k); now[k]=false;
    49 }
    50 
    51 int main()
    52 {
    53     ifstream in("holstein.in");
    54     ofstream out("holstein.out");
    55 
    56     in>>V;
    57     for(int i=1;i<=V;++i) in>>v[i];
    58     in>>G;
    59     for(int k=1;k<=G;++k)
    60         for(int i=1;i<=V;++i) in>>g[k][i];
    61 
    62     r=G+1; go(0);
    63 
    64     out<<r;
    65     for(int k=1;k<=G;++k)
    66         if(good[k]) out<<" "<<k;
    67     out<<endl;
    68 
    69     in.close();
    70     out.close();
    71     return 0;
    72 }
  • 相关阅读:
    11111 Generalized Matrioshkas
    Uva 442 Matrix Chain Multiplication
    Uva 10815 Andy's First Dictionary
    Uva 537 Artificial Intelligence?
    Uva 340 MasterMind Hints
    SCAU 9508 诸葛给我牌(水泥题)
    Uva 10420 List of Conquests(排序水题)
    Uva 409 Excuses, Excuses!
    10/26
    11/2
  • 原文地址:https://www.cnblogs.com/icedream61/p/4343164.html
Copyright © 2011-2022 走看看