【2018寒假集训 Day1】【位运算】桐桐的运输方案

桐桐的运输方案(transp)
【问题描述】
桐桐有 N 件货物需要运送到目的地,它们的重量和价值分别记为:
重量:W1,W2,…,Wn;
价值:V1,V2,…,Vn;
已知某辆货车的最大载货量为 X,并且当天只能运送一趟货物。这辆货车应
该运送哪些货物,才能在不超载的前提下使运送的价值最大?
【输入格式】transp.in
第一行是一个实数,表示货车的最大载货量 x(1<x≤100)。
第二行是一个正整数,表示待运送的货物数 n(1<n≤20)。
后面 n 行每行两个用空格隔开的实数,分别表示第 1 至第 n 件货物的重量 W
和价值 V。
【输出格式】transp.out
第一行为被运送货物的总价值(只输出整数部分);
第二行为按编号大小顺序输出所有被运送货物的编号(当一件都不能运送
时,不输出)。
【输入样例】
20
4
3.5 4
4 5
5 6.8
6.9 7
【输出样例】
22
1 2 3 4
【解题思路】
首先这题有实数运算,排除DP,再看数据范围,可以看出用二进制枚举可解,当然回溯也是可行的。
运用二进制枚举需要掌握基本的位运算
左移符号<< 相当于*2
右移符号>> 相当于/2
&是位运算中的符号,和熟悉的逻辑运算符&&基本相符
100&110=100
即只有两者为1时才返回1
表示一组物品选或不选的状态可以用一个0至2^n-1的整数表示,化成二进制后只要是1就代表着选这个物品。
【参考程序】

#include<iostream>
#include<cstdio>
using namespace std;
int n,record;
double x,ansv,answ,w[21],v[21],maxans;
int main()
{
    freopen("transp.in","r",stdin);
    freopen("transp.out","w",stdout);
    cin>>x>>n;
    for (int i=1;i<=n;i++) cin>>w[i]>>v[i];
    int num=1<<n;//计算枚举的范围 
    for (int i=0;i<num;i++)//从全不选到全选,依次枚举 
    {
        int tmp=1;
        ansv=answ=0;
        for (int j=0;j<n;j++)
        {
            if (((tmp<<j)&i)>0) //判断当前物品是否被选 
            {
                ansv+=v[j+1];
                answ+=w[j+1];
                //装车 
            }
            if (answ>x) break;//超载,此情况不可选 
        }
        if (answ>x) continue; 
        if (ansv>maxans)
        {
            maxans=ansv;//记录答案 
            record=i;
        }
    }
    cout<<int(maxans)<<endl;
    int tmp=1;
    for (int j=0;j<n;j++)
    {
        if (((tmp<<j)&record)>0) cout<<j+1<<" ";//判断当前物品是否被选 
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值