博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P1582 倒水 解题报告
阅读量:4359 次
发布时间:2019-06-07

本文共 844 字,大约阅读时间需要 2 分钟。

P1582 倒水

题目描述

一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)

显然在某些情况下CC无法达到目标,比如N=3,K=1。此时CC会重新买一些新的瓶子(新瓶子容量无限,开始时有1升水),以到达目标。

现在CC想知道,最少需要买多少新瓶子才能达到目标呢?

输入输出格式

输入格式:

一行两个正整数,\(N,K(1≤N≤2×10^9,K≤1000)\)

输出格式:

一个非负整数,表示最少需要买多少新瓶子。


题目还是做少了,这几天研究了下数论就想着切题目了。

很明显,这题和二进制有关系。

\(n\)个瓶子,分成若干个\(2^k\)显然才会合法。

如何保证最优呢?发现\(n\)的二进制表示下1的个数即是最优个数,如果最优个数比\(k\)要多,我们考虑加一些瓶子。

取出\(n\)的最低位1和它右边所代表的数字,把这个数字加上去,即可以消去至少一个1。这是一种贪心的思想。

对于求1的个数和取最低位1,我们使用\(lowbit()\)运算,即\(x&-x\)


code:

#include 
int n,k,ans=0;int get(int x){ int sum=0; for(;x;x-=x&-x) sum++; return sum;}int main(){ scanf("%d%d",&n,&k); while(get(n)>k) { ans+=n&-n; n+=n&-n; } printf("%d\n",ans); return 0;}

2018.5.29

转载于:https://www.cnblogs.com/butterflydew/p/9114397.html

你可能感兴趣的文章
js setInterval 启用&停止
查看>>
knockoutJS学习笔记04:监控属性
查看>>
Linux下启动/关闭Oracle
查看>>
session和cookie的区别
查看>>
oracle 数据库、实例、服务名、SID
查看>>
web.xml文件的作用
查看>>
linux下oracle调试小知识
查看>>
alert弹出窗口,点击确认后关闭页面
查看>>
oracle问题之数据库恢复(三)
查看>>
单点登陆(SSO)
查看>>
HR,也确实“尽职尽责”
查看>>
MaxComputer 使用客户端配置
查看>>
20190823 顺其自然
查看>>
阅读《余生有你,人间值得》有感
查看>>
每日英语
查看>>
SpringCloud+feign 基于Springboot2.0 负载均衡
查看>>
【BZOJ5094】硬盘检测 概率
查看>>
mac上n次安装与卸载mysql
查看>>
Python之单元测试——HTMLTestRunner
查看>>
WebNotes(PHP、css、JavaScript等)
查看>>