hdu 5747(数学,贪心)

Aaronson

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 239    Accepted Submission(s): 156

Problem Description
Recently, Peter saw the equation x0+2x1+4x2+...+2mxm=n. He wants to find a solution (x0,x1,x2,...,xm) in such a manner that ∑i=0mxi is minimum and every xi (0≤i≤m) is non-negative.
 
Input
There are multiple test cases. The first line of input contains an integer T (1≤T≤105), indicating the number of test cases. For each test case:

The first contains two integers n and m (0≤n,m≤109).

 
Output
For each test case, output the minimum value of ∑i=0mxi.
 
Sample Input
10
1 2
3 2
5 2
10 2
10 3
10 4
13 5
20 4
11 11
12 3
 
Sample Output
1
2
2
3
2
2
3
2
3
2
 
Source
 
题意: x0+2x1+22x2+...+2m*xm = n 现在已知 n,m,求解最小的 sum(xi)(0<=i<=m).
题解:昨天刷bestcoder别人三分钟就AC了,我用了20+min才有思路,好惭愧..我的想法如果 n 化成二进制的位数小于 m+1 ,那么只要在这m位中添加 0 1 即可得到n,所以最小的和就是 n 化成二进制中间的 1 的个数,然后当 n 的位数大于 m+1 ,那么我就在这 m+1 位上面添加数字,使得其接近 n,我们想如果能够在越高位添加数字,那么就会越接近 n,所以我们从 2m 开始枚举,然后贪心即可。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int _pow(int a,int n){
int ans = ;
while(n){
if(n&) ans = ans*a;
a=a*a;
n>>=;
}
return ans;
} int main()
{
int tcase;
scanf("%d",&tcase);
while(tcase--){
int n,m;
scanf("%d%d",&n,&m);
int k = n;
int cnt = ,ans=;
while(n){
if(n%==) ans++;
cnt++;
n/=;
}
if(cnt<=m+) printf("%d\n",ans);
else{
int t = _pow(,m);
ans = ;
while(k&&t){
ans+=k/t;
k = k%t;
t/=;
}
printf("%d\n",ans);
}
}
return ;
}
上一篇:学生表sid,sname,结果表cid,cname,学生成绩表sid,cid,cscore,最高要求的分数输出候补课程专门命名


下一篇:shim和polyfill有什么区别