您的位置:首页 > 其它

Uva 11384 - Help is needed for Dexter()

2013-11-22 14:32 447 查看
题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2379

题目大意:

有一个从1、2、3、.......n的正整数数列,现在要通过若干次操作将这个数列全部变为0,操作的方法是每次选取任意1个或多个任意位置的数,然后将这几个数同时减去一个一个数。问至少要经过多少次操作才能让数列全部变为0

题目分析:

将[1, n]从中间分成[1, n/2] 和[n/2+1, n]两个部分,分别包含n/2和(n+1)/2个数,将第二部分的数分别减去n/2+1, 第二部分变为[0, (n-1)/2], 第一部分包括第二部分,可得递推公式为:f(n) = f(n/2) + 1; 

代码:

#include <cstdio>

int f(int n)
{
return n == 1 ? 1 : f(n/2)+1;
}

int main()
{
int n;
while(scanf("%d", &n) != EOF)
printf("%d\n", f(n));
return 0;
}

第二种解法:
把那些1到16的答案全都列举出来,很快就发现了一个规律,即答案是1的有1个(2^0),答案是2的有2个(2^1),答案是3的有4个(2^2),诶,有了这个规律,那我们只需要打一个从1到31的表了,内容是dp[i] = 1<<i,这样只要判断输入的那个n ,如果dp[i]<=n<dp[i+1]的话,那就说明答案就是i。这样在空间上大大的优化了,时间上也大大的优化了。

代码:

#include<cstdio>
int dp[40];
void dabiao() {
int c=1;
for(int i=0;i<=31;++i)
dp[i] = c<<i;
}
int main() {
int n;
dabiao();
while(scanf("%d",&n)!=EOF)
for(int i=0;i<=31;++i)
if(n>=dp[i]&&n<=dp[i+1]-1)
printf("%d\n",i+1);
return 0;
}

http://www.cnblogs.com/xiaxiaosheng/p/3147365.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp Uva11384