HDU_2079_(01背包)(dfs)

选课时间(题目已修改,注意读题)

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4478    Accepted Submission(s): 3480

Problem Description

又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别)

Input

输入数据的第一行是一个数据T,表示有T组数据。
每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。
接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。

Output

对于每组输入数据,输出一个整数,表示学n个学分的组合数。

Sample Input

2

2 2

1 2

2 1

40 8

1 1

2 2

3 2

4 2

5 8

6 9

7 6

8 8

Sample Output

2

445

最开始用多重背包做,发现二进制优化多出的零头可能发生重复,但是没相处解决方案。

看题解用的01背包,稍作修改避免了重复。

因为数据规模小,用dfs也很方便。

01背包:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int cost[10],num[10],dp[45],n;

void zero_one(int cost,int num)
{
    for(int j=n;j>=cost;j--)
        for(int k=1;k<=num&&j-k*cost>=0;k++)
            dp[j]+=dp[j-cost*k];
}

int main()
{
    int t,k;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        scanf("%d%d",&n,&k);
        for(int i=0;i<k;i++)
        {
            scanf("%d%d",&cost[i],&num[i]);
            if(cost[i]*num[i]>n)
                num[i]=n/cost[i];
            //dp[cost[i]]=1;
        }
        for(int i=0;i<k;i++)
        {
            zero_one(cost[i],num[i]);
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}

dfs:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int cost[10],num[10],res,n,k;

void dfs(int index,int sum)
{
    if(index>k||sum>n)
        return;
    if(index==k&&sum!=n)
        return;
    if(sum==n)
    {
        res++;
        return;
    }
    for(int i=0;i<=num[index];i++)
    {
        dfs(index+1,sum+i*cost[index]);
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        res=0;
        scanf("%d%d",&n,&k);
        for(int i=0;i<k;i++)
            scanf("%d%d",&cost[i],&num[i]);
        dfs(0,0);
        printf("%d\n",res);
    }
    return 0;
}
时间: 2024-10-09 06:24:17

HDU_2079_(01背包)(dfs)的相关文章

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

题目链接:http://acm.swust.edu.cn/problem/465/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 吴奶奶有个可爱的外孙女——琪琪,她很喜欢小动物,尤其喜欢养鱼.为了让小孙女养到漂亮的小鱼,吴奶奶一大早就到花鸟鱼虫市场买鱼.这个市场可真大,里面有各种各样的宠物,就连宠物鱼都有好几十种.这些鱼实在是太美了,买的人越来越多,可是因为货源有限,卖鱼的老板不得不规定:同一种鱼,每个人最多只能买一条,并且有些

hdu3448 01背包+dfs

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3448 Description 0/1 bag problem should sound familiar to everybody. Every earth man knows it well. Here is a mutant: given the capacity of a bag, that is to say, the number of goods the bag can ca

POJ3628 Bookshelf 2(01背包+dfs)

Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8745   Accepted: 3974 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly, and now the only available

Bookshelf 2 poj3628(01背包/DFS)

http://poj.org/problem?id=3628 题意:现有一个书架,N头牛,农场主想把这些牛放在书架上,当然,书架是有固定的高度的.现在问你在这些牛之中,其中一些牛的高度加在一块比书架高的最小差值是多少? 分析: 两种方法:(1)01背包,算得所有牛的高度,然后dp一遍,再找比书架高的最小值,两数相减即可.           (2)DFS,DFS(牛的坐标, 牛高度的总和),若在DFS过程中,牛高度的总和>=书架高度,则可以求我们所需要的值 01背包: #include<std

codeforces 842C Ilya And The Tree (01背包+dfs)

(点击此处查看原题) 题目分析 题意:在一个树中,有n个结点,记为 1~n ,其中根结点编号为1,每个结点都有一个值val[i],问从根结点到各个结点的路径中所有结点的值的gcd(最大公约数)最大是多少,其中,我们可以将路径中某一个结点的值变为0,也可以选择不变. 思路:注意到对于每个结点,我们可以选择这个结点,或者不选这个结点(将权值记为0),因而有点01背包的感觉,而我们求gcd的时候需要取所有情况中的最大值 那么我们从根结点开始,每经过一个结点,就从其父节点的所有情况转移得到当前结点的状态

UVA 624 CD (01背包+打印路径 或 dfs+记录路径)

Description You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music is on CDs. You need to have it on tapes so the problem to solve is: you have a tape N minutes long. How to choose tracks from CD to get most o

hdoj 1864 最大报销额 【01背包】||【dfs】

最大报销额 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17014    Accepted Submission(s): 4959 Problem Description 现有一笔经费可以报销一定额度的发票.允许报销的发票类型包括买图书(A类).文具(B类).差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的

hdu 1561The more, The Better(树形dp&amp;01背包)

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4949    Accepted Submission(s): 2918 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

HDU2602(01背包)

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 44257    Accepted Submission(s): 18442 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bon