2019_GDUT_新生专题 I --- D,F

D:[HDU] 2660 — Accepted Necklace

原题链接:https://vjudge.net/problem/30447/origin

题目大意:

给出N个石头及其每个石头的价值和重量,选取K个石头,重量之和不大于给定的W,来做成项链,要求构成项链的石头的价值之和最大,输出这个最大值。

题目分析:

通过深度优先搜索,不足K个石头则继续选择,直到选了K个石头,只要不超过重量限制,更新最大价值。然后放弃最后所选的石头,选择下一个,重复程序,直到K个石头做成的项链被全部遍历,就可以得出答案。

代码实现:

#include <iostream>
#include <cstdio>

using namespace std;

int n, k, want_w; //want_w:项链不超过的重量
int num; //已选的石头数目
int weight, value; //已选的石头的总重量,总价值
int max_v; //最大价值

typedef struct
{
    int v;
    int w;
    int b;
}stone;
stone a[22];

//i为已选中石头数目,
void dfs(int i)
{
    if(num == k){ //所选石头数目达到 k,更新最大价值
        if(weight <= want_w && value > max_v) max_v = value;
    }
    else{
    for(; i<n; i++){
        if(!a[i].b){ //没有被选中
            num++;
            weight += a[i].w;
            value += a[i].v;
            a[i].b = 1; //标记被选中
            dfs(i+1); //选择下一个石头
            num--; //放弃所选的最后一个石头
            weight -= a[i].w;
            value -= a[i].v;
            a[i].b = 0;
        }
    }

    }
}

int main()
{
    int t, i;

    cin >> t;
    while(t--)
    {
        num = 0;
        weight = 0;
        value = 0;
        max_v = 0;
        cin >> n >> k;
        for(i=0; i<n; i++){
            cin >> a[i].v >> a[i].w;
        }
        cin >> want_w;
        dfs(0);
        cout << max_v << endl;
    }

    return 0;
}


F:[POJ] 1426 — Find The Multiple

原题链接:https://vjudge.net/problem/15205/origin

题目大意:

给定一个不大于200的数字,输出它的一个非零倍数,这个倍数需要满足在十进制表示上的每个位只能为0或1,位数不会超过100位。

题目分析:

刚开始读完题,以为这个倍数会很大,long long 都存储不下,难道是用数组?不过后面知道了这个倍数在long long里就可以被找到,那就直接从1开始,然后重复乘以10或者乘以10再加1,通过深度优先搜索完成。

代码实现:

#include <iostream>
#include <cstdio>

using namespace std;

long long a;
long long ans;
void bfs(int n, long long b)
{
    if(n>19) return; //防止倍数的位数超过20位
    if(ans == 0){ 
        if(b%a == 0) ans = b; //找到答案
        else{
            bfs(n+1,b*10);
            bfs(n+1,b*10+1);
        }
    }

}

int main()
{
    cin >> a;
    ans = 0;
    while(a){
        ans = 0;
        bfs(1,1);
        cout << ans << endl;
        cin >> a;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值