[Swust OJ 465]--吴奶奶买鱼(0-1背包+dfs)

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

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 }

时间: 2024-07-30 04:27:02

[Swust OJ 465]--吴奶奶买鱼(0-1背包+dfs)的相关文章

swust oj 1026--Egg pain&#39;s hzf

题目链接:http://acm.swust.edu.cn/problem/1026/ Time limit(ms): 3000 Memory limit(kb): 65535 hzf is crazy about reading math recently,and he is thinking about a boring problem. Now there are n integers Arranged in a line.For each integer,he wants to know

SWUST OJ Euclid&#39;s Game(0099)

Euclid's Game(0099) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 1855 Accepted: 589 Description Starts with two unequal positive numbers (M,N and M>N) on the board. Two players move in turn. On each move, a player has to write on the boar

swust oj 649--NBA Finals(dp,后台略(hen)坑)

题目链接:http://acm.swust.edu.cn/problem/649/ Time limit(ms): 1000 Memory limit(kb): 65535 Consider two teams, Lakers and Celtics, playing a series of NBA Finals until one of the teams wins n games. Assume that the probability of Lakers winning a game is

线段树 [SWUST OJ 764] 校门外的树 Plus Plus

校门外的树 Plus Plus(0764) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 214 Accepted: 15 Description 西南某科技大学的校门外长度为 L 的公路上有一排树,每两棵相邻的树之间的间隔都是 1 米.我们可以把马路看成一个数轴,马路的一端在数轴 1 的位置,另一端在 L 的位置:数轴上的每个整数点,即 1,2,……,L,都种有一棵树. 现在要将这排树的某一段涂成某种颜色,给定 N 组区间[ 

背包 [POJ 2184 SWUST OJ 145] Cow Exhibition

Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9479   Accepted: 3653 Description "Fat and docile, big and dumb, they look so stupid, they aren't much  fun..."  - Cows with Guns by Dana Lyons The cows want to prove to

[Swust OJ 404]--最小代价树(动态规划)

题目链接:http://acm.swust.edu.cn/problem/code/745255/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和. 例如:((4+1)+ (2+3))=((5)+(5))=10.除去原数不4,1,2,3之外,其余都为中间结果,如5,5,10,将中间结果相加

邻接矩阵存储简单路径(swust oj 1070)

Description 假设无向图G采用邻接矩阵存储,设计一个算法,输出图G中从顶点u到v的所有简单路径. Input 简单路径是指路径上的顶点不重复.第一行为一个整数n,表示顶点的个数(顶点编号为0到n-1),第二行表示顶点u和v的编号,接下来是为一个n*n大小的矩阵,表示图的邻接关系.数字为0表示不邻接,1表示不邻接. Output 输出图G中从顶点u到v的所有简单路径. Sample Input 5 0 3 0 1 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 1 0 1 1

数细胞-swust oj

数细胞(0964) 一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数.编程需要用到的队列及其相关函数已经实现,你只需要完成count函数以及主函数即可. 第一行输入两个整数,分别代表矩阵的行和列 输入m*n的矩阵,由数字0到9组成. 4 10 1 2 3 4 5 1 1 1 6 7 1 0 3 4 5 6 1 5 1 0 2 0 4 5 6 6 1 6 7 1 0 0 6 0 6 6 1 0 8 9 细胞个数. 1

swust oj 简单背包问题(0032) DFS

Description 设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,…wn. 问能否从这n件物品中选择若干件放入背包中,使得放入的重量之和正好为S. 如果有满足条件的选择,则此背包有解,否则此背包问题无解. Input 输入数据有多行,包括放入的物品重量为s,物品的件数n,以及每件物品的重量(输入数据均为正整数) 多组测试数据. Output 对于每个测试实例,若满足条件则输出“YES”,若不满足则输出“NO“ Sample Input 20 5 1 3 5 7