BJTU1935 铁憨憨骑士团的购买装备

BJTU1935 铁憨憨骑士团的购买装备

题目:

在遥远的憨憨王国,有一个铁憨憨骑士团。

这天,憨帕斯正在参加骑士团第一届全团OGSC大赛。在当前的版本,OGSC一共有 𝑛
种装备可供购买,其中第 𝑖 种装备的价格是 𝑎𝑖

元。在一局游戏中 ,每一种装备最多只能被购买一次。注意,装备的价格有可能相同,但仍然视作不同的装备,可以被同时购买。

憨帕斯现在手中有 𝑚
块钱。现在,他想要知道,自己有多少种购买装备的方案,能够正好花光手里的 𝑚 块钱?

输入数据:

第一行两个整数 𝑛,𝑚 (1≤𝑛≤20,1≤𝑚≤1018) ,分别表示装备的种类数和憨帕斯手里的钱。
第二行一共 𝑛 个整数,其中第 𝑖 个整数 𝑎𝑖 (1≤𝑎𝑖≤1016) 表示第 𝑖 种装备的价格。

输出数据:

一个整数,表示正好花光 𝑚 块钱的方案数。

样例输入:

输入:

7 4750
4750 2700 1000 400 300 200 150

输出:

2

分析:

数据量不大20,并且要进行决策并判断,显然是深搜递归的思路,20个循环,所以一开始我就每一个循环写的从a[1]a[20]的遍历,使用过的就vis[i] = true。TLE…想想也是,20组数据的话,每一个循环20次运算,20个循环…

所以思考一下怎么优化,20个循环,我们把每次的循环修改为对于第i个装备是否购买的决策,这样基数就是2了,最大O(2^20)。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>

using namespace std;

bool vis[21];
int n;
long long m;
long long ans = 0;
long long a[21] = {0};
long long temp = 0;

void dfs(int now)
{
    if(now == n + 1 || temp <= 0)
    {
        if(now == n + 1)
        {
            if(temp == 0)
            {
                ans++;
            }
            return;
        }
        if(temp == 0)
        {
            ans++;
            return;
        }
        if(temp < 0)
        {
            return;
        }
    }
    for(int i = 1;i >= 0;i--)
    {
        if(i)
        {
            temp -= a[now];
            dfs(now + 1);
            temp += a[now];
        }
        else
        {
            dfs(now + 1);
        }

    }
}

int main()
{
    cin>>n>>m;
    for(int i = 1;i <= n;i++)
    {
        cin>>a[i];
    }
    temp = m;
    memset(vis,false,sizeof(vis));
    dfs(1);
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值