zoukankan      html  css  js  c++  java
  • ICPC2020 济南站 L 题 (数位dp)

    题目链接:

    发现 (m) 很小,所以只需要先数位 (dp),然后暴力枚举后 (8) 位的情况即可,因为涉及到进位,所以还需要维护第八位之前有几个连续的 (1)
    (dp[0/1][i][0/1][0/1]) 表示,当前到第 (i) 位,卡不卡上界,从第 (i) 位向前有多少个连续的 (1)(奇偶), 有多少个 (1) (奇偶)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 110;
    
    int T, m, lev; ll L;
    int a[maxn], c[maxn], d[maxn], cnt = 0;
    int su[600]; 
    ll A1[2][65],A2[2][65];
    
    ll dp[2][65][2][2];
    
    ll dfs(int pos, int sum, int in, int lim){
    	if(dp[lim][pos][sum & 1][in & 1] != -1) return dp[lim][pos][sum & 1][in & 1];
    	if(pos >= cnt + 1 - 8){
    		ll res = 0;
    		if(lim) res += A1[sum & 1][in & 1];
    		else res += A2[sum & 1][in & 1];
    		dp[lim][pos][sum & 1][in & 1] = res;
    		return res;
    	}
    
    	ll res = 0;
    	int li = (lim) ? (c[pos]) : 1;
    	for(int i = 0 ; i <= li ; ++i){
    		if(i == 0) res += dfs(pos + 1, sum + i, 0, lim & (i == li));
    		else res += dfs(pos + 1, sum + i, in + i, lim & (i == li));
    	}
    	dp[lim][pos][sum & 1][in & 1] = res;
    	return res; 
    }
    
    ll calc(ll x){
    	cnt = 0;
    	ll tmp = x;
    	while(tmp){
    		c[++cnt] = tmp % 2ll;
    		tmp /= 2ll;
    	}
    	
    	for(int i = 1 ; i <= cnt / 2 ; ++i) swap(c[i], c[cnt - i + 1]);
    		for(int sum=0;sum<=1;++sum){
    			for(int in = 0;in <= 1;++in ){
    				for(int i = 0 ; i <= lev ; ++i){
    					int tmp=1;
    					for(int j = 0 ; j < m ; ++j){			
    						if(i+j>=256){
    							tmp &= (((sum + su[i+j] - in)%2+2)%2== a[j]);
    						}else{
    							tmp &= (((sum + su[i+j]) % 2+2)%2 == a[j]);
    						}
    					}
    					A1[sum][in]+=tmp; 
    				}
    				for(int i = 0 ; i < 256 ; ++i){
    					int tmp=1;
    					for(int j = 0 ; j < m ; ++j){			
    						if(i+j>=256){
    							tmp &= (((sum + su[i+j] - in)%2+2)%2== a[j]);
    						}else{
    							tmp &= (((sum + su[i+j]) % 2+2)%2 == a[j]);
    						}
    					}
    					A2[sum][in]+=tmp; 
    				}
    			}
    		}
    	return dfs(1, 0, 0, 1);
    }
    
    int main(){
    	scanf("%d", &T);
    	for(int i = 0 ; i < 512 ; ++i){
    		int tmp = i;
    		while(tmp){
    			su[i] += (tmp & 1);
    			tmp >>= 1;
    		}
    	}
    	while(T--){
    		memset(dp, -1, sizeof(dp));
    		memset(A1,0,sizeof(A1)); 
    		memset(A2,0,sizeof(A2));
    		scanf("%d%lld", &m, &L);
    		lev = L % (1 << 8);
    		for(int i = 0 ; i < m ; ++i) scanf("%d", &a[i]);
    		
    		printf("%lld
    ", calc(L));
    	}
    	return 0;
    }
    
  • 相关阅读:
    Mac使用pip安装Tensorflow
    php之curl get post curl_multi_exec 请求用法
    重新捡起的知识-字节(Byte)、比特(bit)-计算机常识
    Mac打不开Wireshark dyld: Library not loaded: /usr/X11/lib/libcairo.2.dylib
    ViewController生命周期
    转 try catch finally
    VPS centOS搭建gitlab小结
    UIButton小节
    python 统计单词个数,并按个数与字母排序
    GCP 谷歌云平台申请教程
  • 原文地址:https://www.cnblogs.com/tuchen/p/14204100.html
Copyright © 2011-2022 走看看