没有想到这是一个DP
方法零:
递归暴搜,铁定TLE
int ans=1;
int search(int n)
{
for(int i=1;i<=(n/2);i++)
{
search(i);
ans++;
}
}
int main()
{
int n;
scanf("%d",&n);
search(n);
printf("%d",ans);
return 0;
}
方法一:
首先不难发现 a n s [ n ] = ∑ i = 1 n / 2 a n s [ i ] + 1 ans[n]=\sum_{i=1}^{n/2}ans[i]+1 ans[n]=i=1∑n/2ans[i]+1所以暴力循环就可以了,毕竟数据很弱,n<=1000.
#include<stdio.h>
int ans[1001]={0};
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
ans[i]=1;
for(int j=1;j<=(i/2);j++)
{
ans[i]+=ans[j];
}
}
printf("%d\n",ans[n]);
return 0;
}
方法三(引用洛谷@vegetabird写的题解,侵删)
每从一个奇数2n+1到下一个偶数时2n+2时,2n+2左面的数就比2n+1时多了n+1的情况,因此:
a
n
s
[
2
n
+
2
]
=
a
n
s
[
2
n
+
1
]
+
a
n
s
[
n
+
1
]
ans[2n+2]=ans[2n+1]+ans[n+1]
ans[2n+2]=ans[2n+1]+ans[n+1]
是一个DP,状态转移方程:
a
n
s
[
n
]
=
{
a
n
s
[
n
/
2
]
+
a
n
s
[
n
−
1
]
n为偶数
a
n
s
[
n
−
1
]
n为奇数
1
n=1
ans[n]= \begin{cases} ans[n/2]+ans[n-1]& \text{n为偶数}\\ ans[n-1]& \text{n为奇数}\\ 1&\text{n=1} \end{cases}
ans[n]=⎩⎪⎨⎪⎧ans[n/2]+ans[n−1]ans[n−1]1n为偶数n为奇数n=1
#include<stdio.h>
int ans[1001]={0};
int main(){
int n;
scanf("%d",&n);
ans[1]=1;
for(int i=2;i<=n;i++)
{
if(i%2==0)
ans[i]=ans[i-1]+ans[i/2];
else
ans[i]=ans[i-1];
}
printf("%d\n",ans[n]);
return 0;
}