链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2379
题目大意
n n 项数列,每次可以选择任何几个数减去相同的值,问你最少几次全变成 0 0
题解
其实答案取决于一开始又多少不同的值,如果操作之后值变多了,那这次操作肯定是不对的,只会徒增花费。
看一下
1 2 3
1 0 1
0 0 0
两次变成全0,所以答案是2
看一下
n=4
n
=
4
1 2 3 4
1 2 0 1
0 2 0 0
0 0 0 0
答案是
3
3
从这里就可以看出,我第一步执行完之后,就变成了f[2]的子问题
所以我只需要确定递推关系即可
对于为奇数,我只要从第
⌊n2⌋+1
⌊
n
2
⌋
+
1
项开始减去
⌊n2⌋+1
⌊
n
2
⌋
+
1
,就变成
⌊n2⌋
⌊
n
2
⌋
的子问题,且
fn=f⌊n/2⌋+1
f
n
=
f
⌊
n
/
2
⌋
+
1
对于
n
n
为偶数,我只要从第项开始减去
n2+1
n
2
+
1
,就转化成了
n2
n
2
的子问题,
fn=fn/2+1
f
n
=
f
n
/
2
+
1
综上
fn=f⌊n2⌋+1
f
n
=
f
⌊
n
2
⌋
+
1
,
f0=1
f
0
=
1
时间复杂度
O(log2n)
O
(
log
2
n
)
代码
#include <cstdio>
int dfs(int n)
{
if(n==0)return 0;
return dfs(n/2)+1;
}
int main()
{
int n;
while(~scanf("%d",&n))printf("%d\n",dfs(n));
return 0;
}