zoukankan      html  css  js  c++  java
  • [Swust OJ 465]--吴奶奶买鱼(0-1背包+dfs)

    题目链接:http://acm.swust.edu.cn/problem/465/

    还有一道题只是描述不一样,方法一模一样(http://acm.swust.edu.cn/problem/644/

    Time limit(ms): 1000        Memory limit(kb): 65535
     
    Description
    吴奶奶有个可爱的外孙女——琪琪,她很喜欢小动物,尤其喜欢养鱼。为了让小孙女养到漂亮的小鱼,吴奶奶一大早就到花鸟鱼虫市场买鱼。这个市场可真大,里面有各种各样的宠物,就连宠物鱼都有好几十种。这些鱼实在是太美了,买的人越来越多,可是因为货源有限,卖鱼的老板不得不规定:同一种鱼,每个人最多只能买一条,并且有些鱼是不能一起买的,因为它们之间会互相争斗吞食。 
    吴奶奶想尽可能地买多些鱼,但可惜,她的资金有限,这可怎么办好呢?请编写一个程序帮助她。如果有多个方案都能买到尽可能多的鱼,则选择所花资金最多的一个。
     
    Input
    输入文件的第一行为两个正整数M(M≤1000),N(N≤30),分别表示吴奶奶的资金和鱼的种类。以下N行,每行有两个正整数S(1≤S≤N),T,分别表示某种鱼的编号以及该鱼的价格。 
    接着,每行有两个整数P,Q。当P,Q大于0时,表示P,Q不能共处;当P,Q均等于0时,表示输入文件的结束。
     
    Output
    文件的第一行为两个正整数X,Y,分别表示所买鱼的条数和总花费。以下X行,每行有一个整数,表示所买鱼的编号。编号按升序排列输出。 
    如果题目有多个解,只需输出其中一个。
     
    Sample Input
    170 7
    1 70
    2 50
    3 30
    4 40
    5 40
    6 30
    7 20
    1 4
    1 7
    3 4
    3 5
    5 7
    6 7
    0 0

    Sample Output
    4 160
    2
    4
    5
    6

     
    Hint
     
     
    解题思路:这道题除去鱼之间的相互吞食,和输出所购买的鱼,就是一个0-1背包问题。
         现在在0-1背包的基础上为了达到以上两点设计一个dfs算法,递归模拟这个过程,在代码中有详细的注释,这里就不多说了~~~
     
    代码如下:
     1 /******************0-1背包+dfs******************/
     2 #include <iostream>
     3 using namespace std;
     4 
     5 #define rep(i,a,b) for(int i=a;i<=b;i++)
     6 
     7 int buy[31], sign[31];//sign标记鱼的购买状态,buy最优购买方案
     8 int mpt[31][31];//表示鱼的相互克制状态
     9 int val, num, n, m, vi[31];//vi价格
    10 
    11 void dfs(int cur, int sum, int cnt){
    12     int ptr[31];//中转变量
    13     if (cur > n){
    14         if (num<cnt || (num == cnt&&sum>val)){
    15             num = cnt;
    16             val = sum;
    17             rep(i, 1, n)buy[i] = sign[i];
    18         }
    19         return;
    20     }
    21     if (!sign[cur] && sum + vi[cur] <= m){
    22         rep(i, 1, n) ptr[i] = sign[i];
    23         sign[cur] = 2;//标记这条鱼已购买
    24         rep(i, 1, n){
    25             if (mpt[cur][i] && !sign[i])
    26                 sign[i] = 1;
    27         }
    28         dfs(cur + 1, sum + vi[cur], cnt + 1);
    29         //还原鱼的购买状态,方便下一次搜索
    30         rep(i, 1, n) sign[i] = ptr[i];
    31         sign[cur] = 0;
    32     }
    33     dfs(cur + 1, sum, cnt);
    34 }
    35 int main(){
    36     int a, b;
    37     cin >> m >> n;
    38     //鱼不一定按顺序给出,坑爹啊~~
    39     rep(i, 1, n){
    40         cin >> a;
    41         cin >> vi[a];
    42     }
    43     cin >> a >> b;
    44     while (a || b){
    45         mpt[a][b] = mpt[b][a] = 1;
    46         cin >> a >> b;
    47     }
    48     dfs(1, 0, 0);
    49     cout << num << ' ' << val <<endl;
    50     rep(i, 1, n){
    51         if (buy[i] == 2)
    52             cout << i << endl;
    53     }
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    web.xml中openEntityManagerInViewFilter的作用(转)
    JNDI解读(转)
    Java读取大文件的高效率实现
    快速入门react
    谈一谈我所了解的https
    漫谈JWT
    Java 中的几种线程池这么用才是对的
    用Vue来实现图片上传多种方式
    一个页面从输入URL到页面加载显示完成,这个过程都发生什么?
    “===”与“==”的区别
  • 原文地址:https://www.cnblogs.com/zyxStar/p/4589246.html
Copyright © 2011-2022 走看看