2017.10.22_数位dp模板分析
数位dp模板分析:
pos:当前处理的位置——一般由高位到低位
pre:上一位的数字
status:要达到的状态,如果为1则可以认为找到了答案,到时候用于返回,给计数器加一
limit:是否受限,例:567,当前处理6这位(十位),如果前边取的是4,则可以在十位取0—9,前边取的数等于5,则十位数字就要限制在0—6,此时的limit为1作为标志
dp[pos][pre][status]数组保存这三个状态是因为往后转移的时候会遇到很多重复的情况
dfs(int pos,int pre,int status,int limit)
{
if(pos<1)//已经搜到了尽头,返回1
return 1;
if(!limit&&dp[pos][pre][limit]!=-1)//dp里保存的是完整的,即不受限的答案,如果满足的话,就直接返回
return dp[pos][pre][limit];
int end=limit==1?dig[pos]:9;
int ret=0;
for(int i=0;i<=end;i++)
{
ret+=dfs(pos-1,i,status||(pre==4&&i==9),(limit==1)&&(i==end));
//往下搜的状态很巧妙,status用||表示如果前面找到了答案那么后边有没有就无所谓了,而limit用&&是因为只有前面受限,当前首先才能推出下一步也受限,,比如789,如果十位取了8,而百位小于7,则个位可随便取,而当十位取了8,百位取了7,个位就有限制了。上边用没有49做例子。
}
if(!limit)
dp[pos][pre][satus]=ret;
return ret;
}
还有很多例题没有看,感觉数位dp'还是很好理解的。