首页 > 其他分享 >CodeForces - 914C Travelling Salesman and Special Numbers

CodeForces - 914C Travelling Salesman and Special Numbers

时间:2022-11-04 19:13:06浏览次数:50  
标签:cnt 二进制 914C ll CodeForces Numbers ans 1005 define

题意:给出一个二进制数a,每次操作将当前数变成其二进制下1的个数,若干次操作后可以将其变为1.给定k,求不大于a的数中,经过k次操作能变成1的数的数量。

解:观察一下这个操作,可以求出1000以内的数变成1的次数,设其为cnt[i]。对于1000以外的数,可以在一次操作后变到1000以内。枚举i,如果cnt[i]+1=k,那就说明二进制下拥有i个1的数,能在k次操作后变成1.接下来问题变成了有多少小于等于a的,二进制下有i个1的数。进行一些数位dp。

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxx 100005
#define maxn 25
#define maxm 205
#define ll long long
#define inf 1000000009
#define mod 1000000007
char a[1005];
int len;
ll dp[1005][1005][2]={0};
int cnt[1005]={0};
int k;
ll dfs(ll pos,ll kk,ll limit){
    if(pos==len+1) {
        return kk==0;
    }
    if(kk<0)
        return 0;
    if(!limit&&dp[pos][kk][limit]!=-1)
        return dp[pos][kk][limit];
    ll ret=0;
    ll res=limit?a[pos]-'0':1;
    for(int i=0;i<=res;i++){
        ret=(ret+dfs(pos+1,kk-i,limit&&(i==a[pos]-'0')))%mod;
    }
    return !limit?dp[pos][kk][limit]=ret:ret;
}
signed main() {
//    int T;
//    scanf("%d",&T);
//    while(T--) {;
//
//    }
    memset(dp,-1,sizeof dp);
    scanf("%s",a+1);
    scanf("%d",&k);
    if(k==0){
        printf("1\n");
        return 0;
    }
    len=strlen(a+1);
    ll ans=0;
    for(int i=1;i<=1000;i++){
        if(i>1) {
            bitset<1005> b = i;
            cnt[i] = cnt[b.count()] + 1;
        }
        if(cnt[i]==k-1) {
            ans = (ans + dfs(1, i, 1)) % mod;
        }
    }
    if(k==1) ans--;
    printf("%lld\n",ans);
    return 0;
}
View Code

 

标签:cnt,二进制,914C,ll,CodeForces,Numbers,ans,1005,define
From: https://www.cnblogs.com/capterlliar/p/16858842.html

相关文章

  • Codeforces Round #776 (Div. 3) E
    E.ReschedulingtheExam显然我们能想到的每次操作都是先将最小的取出来操作要是我们有两个数都是最小的我们只有相邻的时候才能操作要是大于两个那我们就不管怎么操......
  • Codeforces Round #778 (Div. 1 + Div. 2, based on Technocup 2022 Final Round) F M
    A-E都还是比较简单的。首先,容易想到的,异或上\(2^k\),相当于以\(2^{k+1}\)的长度分块,然后每一块对半切,然后交换左右部分。我的想法是由于这个交换的性质,也许我们可以尝......
  • Codeforces Round #766 (Div. 2)
    CodeforcesRound#766(Div.2)\(\color{Green}{★}\)表示赛时做出。\(\color{Yellow}{★}\)表示赛后已补。\(\color{Red}{★}\)表示\(\text{To\be\solved}\)......
  • Codeforces Round #820 (Div. 3) F
    F.KireiandtheLinearFunction首先我们知道的是给定长度w都是%9意义下的所以我们枚举四个位置的数就是9^4预处理出来答案这里我们要去w长度的串%9但是w的位数过......
  • Codeforces Global Round 20 D F1 F2/more
    https://codeforc.es/contest/1672F1https://www.luogu.com.cn/blog/AlexWei/solution-cf1672f1将置换分解为若干轮换(环),悲伤值越大\(\Rightarrow\)环越少(设环为\(k......
  • Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2) D
    D.ExplorerSpace我们考虑一个性质就是他最多就是找到一条k/2的最短路径然后回来这样是肯定是包含最优解的这个观察第二个样例我们将其改变一下要是我们一半的长度......
  • CodeForces 1540B Tree Array
    CF传送门洛谷传送门很强的一个题。发现根的选择很重要,于是考虑先枚举根。考虑枚举两个点对\(i,j\(i<j)\),如果\(j\)比\(i\)先被标记,那么\(i,j\)就贡献了一个逆......
  • CodeForces - 204A Little Elephant and Interval
    题意:给定区间[l,r],问区间内有多少第一个数字和末尾数字一样的数。解:练习一些数位dp。先从高到低dp[pos][fir]表示dp到第pos个位置,以fir开头的串的数量,其中fir不为0。这道......
  • Codeforces Round #610 (Div. 2) C
    C.PetyaandExamhttps://codeforces.com/contest/1282/problem/C考虑贪心先对于时间排序然后贪心我们可以不考那我们可以在此之前离开然后在离开之前这段时间多做......
  • Codeforces Round #634 (Div. 3) E
    E2.ThreeBlocksPalindrome(hardversion)我们考虑一种最优构造对于一个数x我们肯定要的是他的前几个再最后几个中间选最多的一个数这样显然是最优的我们枚举x......