• 2020CCPC长春 D. Meaningless Sequence(打表/数位DP)


    Once there was a mathematician, who was obsessed with meaningless number sequences. Here is one of them.

    ={1,⋅max0≤<&,=0otherwise,an={1,n=0c⋅max0≤i<nan&⁡i,otherwise,

    where && denotes the bitwise AND operation.

    As a mathematician, he could easily tell what an was for any n, but he wanted to test you. You are required to tell him

    (∑=0)mod(109+7)(∑i=0nai)mod(109+7)

    to convince him that you have a deep understanding of this (although meaningless) sequence.

    先打一个表找规律,发现其实很难看出来。考虑到规律可能与c的取值无关,于是打印一下每个位置n对应的最大的\(a_{n \& i}\)所在的位置,发现这个位置实际上就是n去掉最高位的1,于是每个位置n对应的值实际上就是\(c^{n的二进制表示中1的个数}\)。由于答案要求所有数的和,且注意到位与位之间彼此无关,可以考虑数位dp求解。设dp[i, j, k]表示当前遍历到len,且当前位为j,是否紧贴边界为k的答案。直接套板子即可。

    #include <iostream>
    #define ll long long
    #define mod 1000000007
    using namespace std;
    //string n;
    ll c;
    string n;
    ll fpow(ll a, ll b) {
    	ll ans = 1;
    	for(; b; b >>= 1) {
    		if(b & 1) ans = ans * a % mod;
    		a = a * a % mod;
    	}
    	return ans;
    }
    ll get(ll x) {
    	int ans = 0;
    	while(x) {
    		if(x & 1) ans++;
    		x >>= 1;
    	}
    	return ans;
    }
    ll dp[3005][2][2];
    bool num[3005];
    int nn = 0;
    ll dfs(ll len, bool pre, bool tight) {
    	if(dp[len][pre][tight]) return dp[len][pre][tight];
    	if(len == 0) return 1;
    	ll ans = 0;
    	for(ll i = 0; i < 2; i++) {
    		if(i == 0) ans = (ans + dfs(len - 1, 0, tight && (i == num[len]))) % mod;
    		else {//这一位如果是1的话,上一位肯定不能是1,同时要注意不能超边界
    			if(i > num[len] && tight) continue;
    			ans = (ans + c * dfs(len - 1, 1, tight && (i == num[len])) % mod) % mod;
    		}
    	}
    
    	return dp[len][pre][tight] = (ans % mod);
    }
    int main() {
    	cin >> n >> c;
    	for(int i = n.size() - 1; i >= 0; i--) {
    		if(n[i] == '0') num[++nn] = 0;
    		else num[++nn] = 1;
    	}
    	//从0到n c的每个数中1的个数次方
    	
    	cout << dfs(nn, 0, 1) % mod;
    	return 0;
    }
    
  • 相关阅读:
    字节跳动2020年九月笔试题-爬楼梯(不能连续爬两个两步)
    c/c++经典面试题-part1
    C++单例模式之一见钟情
    多线程同步的四种方式(史上最详细+用例)
    c++多态之动态绑定
    Redis从入门到入坑
    编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串 是由同一字符组成的。
    面试之进制转换函数
    c++编程题之空调遥控器
    static 和 const关键字的作用
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/15538664.html
Copyright © 2020-2023  润新知