题意:
就是给你一个n,求出f(1)+…+f(n),f(x)的值是,x前面连续1的个数。
思考:
看一眼范围,和按位来考虑那就是数位dp,然后就正常的位,是否连续,总数,这三维就可以了。
代码:
int T,n,m;
int va[N];
int cnt,ans;
int dp[M][M][M];
int f(int x);
int dfs(int pos,int vis,int sum,int limit,int lead);
signed main()
{
IOS;
cin>>n;
cout<<f(n);
return 0;
}
int dfs(int pos,int vis,int sum,int limit,int lead)
{
if(not pos) return sum;
if(!limit&&!lead&&dp[pos][vis][sum]!=-1) return dp[pos][vis][sum];
int up = limit?va[pos]:9;
int res = 0;
for(int i=0;i<=up;i++)
{
int limit_t = limit&&(i==up),lead_t = lead&&(i==0); //通用的
if(lead) res += dfs(pos-1,(i==1),(i==1),limit_t,lead_t); //一般都是lead这里有区分要特定处理
else
{
int vis_t = vis&&(i==1);
if(vis) res += dfs(pos-1,vis_t,sum+(i==1),limit_t,lead_t);
else res += dfs(pos-1,vis_t,sum,limit_t,lead_t);
}
}
if(!limit&&!lead) dp[pos][vis][sum] = res;
return res;
}
int f(int x)
{
mem(dp,-1);
cnt = 0;
while(x)
{
va[++cnt] = x%10;
x /= 10;
}
return dfs(cnt,1,0,1,1);
}
总结:
多多复习,总结一下维的确定。