关注
/*
dfs实际上是个模拟
*/
//len表示判断的是哪一位
ll dfs(ll len,int maxi,int k,int f){
//dp[len][k][f]存储的是到长度为len为止,第k位为0和第k位为1的数是多少
//maxi标志的是上一位模拟的数是不是等于num的这一位的数
/*
我们还是拿100来举例子,因为最高位我们得到的一定为1,所以传进来的时候maxi就是1
那么我们第一位既可以模拟0也可是模拟1
模拟0的时候,i != a[len]所以maxi = false,之后也都是false
我们下一位就可以模拟00X跟01X,剩下的类似
模拟1的时候,i == a[len]所以maxi = true
我们就可以模拟1XX
但是由于这时a[2] = 0所以只能模拟10X
差不多就已经很清楚了
*/
//dp[len][k][f]这里其实就是记忆化搜索,如果之前出现过,就直接返回结果就好。
if(dp[len][k][f] != -1 && maxi == 0)
return dp[len][k][f];
//只有当第k位为1的情况这里才会加上1
if(!len)
return f;
ll cnt = 0;
int maxn = maxi ? a[len] : 1;
//i这里代表着第len位的数字是多少
//那么f||len == k && i就是判断这次模拟的数的第k位是否为1
for(int i = 0;i <= maxn;i++){
cnt += dfs(len - 1,maxi && i == a[len],k,f||len == k&&i);
}
//只有当maxi等于false的时候,我们模拟了下一位为0,1的全部情况,此时才更新dp的值
//表示不受之前的数的限制,所求的只是[0,1 << (len) - 1]]满足条件的数
return maxi ? cnt : dp[len][k][f] = cnt;
}
//二进制拆分数位,返回的结果是第k位为1的数总共有几个
ll div(ll num,int k){
memset(a,0,sizeof(a));
int index = 0;
while(num){
a[++index] = num % 2;
num /= 2;
}
return dfs(index,1,k,0);
}
E题最简单数位DP标程,本菜鸡的一点个人解读,希望可以帮到跟我一样的萌新新理解,个人一点愚见,如果有不正确的地方,还请大佬们们斧正ORZ
查看原帖
5 评论
相关推荐
点赞 评论 收藏
分享
牛客热帖
更多
正在热议
更多
# 什么是优秀的实习经历 #
9088次浏览 223人参与
# 实习简历求拷打 #
15286次浏览 181人参与
# 被上班搭子“传染”了哪些习惯 #
6035次浏览 101人参与
# 作业帮求职进展汇总 #
83730次浏览 550人参与
# 工作后,你落下了哪些病根 #
14310次浏览 193人参与
# 秋招被挂春招仍然能投的公司 #
7389次浏览 103人参与
# 实习要如何选择和准备? #
128475次浏览 1485人参与
# 外包能不能当跳板? #
54224次浏览 256人参与
# 诺瓦星云求职进展汇总 #
233456次浏览 1736人参与
# mt对你说过最有启发的一句话 #
38255次浏览 452人参与
# 公司情报交流地 #
126565次浏览 1227人参与
# 为了找工作你花了哪些钱? #
74825次浏览 361人参与
# 你觉得机械有必要实习吗 #
69754次浏览 485人参与
# 投格力的你,拿到offer了吗? #
153225次浏览 819人参与
# 一起聊美团 #
307473次浏览 1764人参与
# 摸鱼被leader发现了怎么办 #
103121次浏览 654人参与
# 京东开奖 #
631880次浏览 3180人参与
# 秋招特别不鸣谢 #
16331次浏览 186人参与
# 考研失败就一定是坏事吗? #
202087次浏览 1382人参与
# 选实习,你更看重哪方面? #
14883次浏览 224人参与
美的集团公司福利 798人发布