zoukankan      html  css  js  c++  java
  • 北京化工大学程序设计周赛 Contest2173 202120221 ACM集训队每周程序设计竞赛(4) A.异或&加法 (位运算,dp)

    • 题意:给你一个二进制数,求有多少对\((x,y)\)满足图中的两个条件。

    • 题解:对于\(x+y=x\oplus y\),我们知道异或是不进位的,那么就要保证\(x\)\(y\)的任意一位不同时为\(1\),先看\(x+y=n\)的情况,这很容易就能算出来,关键是\(x+y\le n\)怎么搞,我们假设\(dp[0][i]\)表示\(x+y\)的前\(i\)位都与\(n\)的前\(i\)位相同,\(dp[1][i]\)表示\(x+y\)的前\(i\)位至少有一个位置,小于\(n\)对应的位置,那么在这之后,我们随便怎么赋值(除了\((1,1)\),都能满足图中的两个条件。那么:

      假设\(n\)的第\(i\)位是\(0\),有:\(dp[0][i]=dp[0][i-1]\),因为只能选\((0,0\))。\(dp[1][i]=dp[1][i-1]*3\),因为必然合法,\((0,0),(0,1),(1,0)\)随便选

      假设\(n\)的第\(i\)位是\(1\),有:\(dp[0][i]=dp[0][i-1]*2\),因为可以选\((0,1),(1,0)\)\(dp[1][i]=dp[1][i-1]*3+dp[0][i-1]\),这里加上\(dp[0][i-1]\)是因为可以选\((0,0)\)来表示直到当前这个位置才满足小于的情况。

      最后记得初始化,\(dp[0][0]=1\).

    • 代码

      #include <bits/stdc++.h>
      #define ll long long
      #define fi first
      #define se second
      #define pb push_back
      #define me memset
      #define rep(a,b,c) for(int a=b;a<=c;++a)
      #define per(a,b,c) for(int a=b;a>=c;--a)
      const int N = 3e6 + 10;
      const int mod = 1e9 + 7;
      const int INF = 0x3f3f3f3f;
      using namespace std;
      typedef pair<int,int> PII;
      typedef pair<ll,ll> PLL;
      ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
      ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
      
      string s;
      ll dp[2][N];
      
      int main() {
      	cin>>s;
      	int n=(int)s.size();
      	s=" "+s;
      	dp[0][0]=1;
      	for(int i=1;i<=n;++i){
      		if(s[i]=='0'){
      			dp[0][i]=dp[0][i-1];
      			dp[1][i]=dp[1][i-1]*3%mod;
      		}
      		else{
      			dp[0][i]=dp[0][i-1]*2%mod;
      			dp[1][i]=(dp[1][i-1]*3%mod+dp[0][i-1])%mod;
      		}
      	}
      	printf("%lld\n",(dp[0][n]+dp[1][n])%mod);
      	return 0;
      }
      
  • 相关阅读:
    团队项目第二阶段——第一天
    团队项目第一阶段绩效评估
    铁大树洞与市面上现有APP对比
    第一阶段其他组评价汇总
    第一阶段对其他组的评价
    铁大树洞app功能演示和使用说明
    团队冲刺——第十天
    团队冲刺——第九天
    团队冲刺——第八天
    梦断代码读后感04--毁灭即拯救
  • 原文地址:https://www.cnblogs.com/lr599909928/p/15426260.html
Copyright © 2011-2022 走看看