【题解】P1028 数的计算
题面
前言
简单 DP 捏
正文
就这么个东西,一眼爆搜——过不了
但是我们发现一个神奇的事情,结合例子来说吧:
比如说我们前面填了若干个数,当前数是 \(7\),求这个东西本质不同的填数方式
依照题意,我们可以填 \(73\),\(72\),\(71\)……
那么其实接下来填的数就和 \(7\) 及以前的没有关系了
即没有后效性
没有后效性?这不是 DP 吗?
Exactly,其实不论是记忆化搜索还是 DP,都是这个题的正解
我们记 \(f_i\) 表示末尾为 \(i\) 的方案数
转移方程显然有 \(f_i = 1 + {\sum_{j=1}^{i/2} f_j}\)
时间复杂度 \(O(n^2)\)
不再是指数级力,可以通过!
代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1024;
int n,f[maxn];
inline void init(){
memset(f,-1,sizeof(f));
f[1]=1;
return;
}
inline int dfs(int x){
if(f[x]!=-1){
return f[x];
}
int res=0;
for(int i=1;i<=x/2;i++){
res+=dfs(i);
}
return f[x]=res+1;
}
int main(){
init();
cin>>n;
cout<<dfs(n)<<endl;
return 0;
}