zoukankan      html  css  js  c++  java
  • 牛客OI周赛13-提高组A-0还是1(简单DP)

    链接:https://ac.nowcoder.com/acm/contest/2970/A
    来源:牛客网

    题目描述

    给出一个长度为n的操作序列。每个位置为“&”,“|”,“”中的一个。&表示按位与,|表示按位或,表示按位异或。
    定义一个长度为n+1的01数列(即该数列只包含0和1)是合法的,当且仅当将该操作序列插入这个长度为n+1的数列后,运算结果为1。
    具体的讲,如果给出的操作序列为“&|”,将其插入到序列1010中进行运算:1&0|10=1。所以1010就是操作序列“&|^”的一个合法序列。

    这里的运算不考虑运算符之间的优先级,即全部为自左向右依次进行运算。

    现在你需要统计对于一个给定的操作序列,有多少个合法序列。
    由于答案可能很大,你只需要输出答案对1e9+7取模后的结果。

    点击下载大样例

    输入描述:

    第一行一个正整数n,表示给出的操作序列的长度。
    第二行一个长度为n的字符串,表示给出的操作序列。
    

    输出描述:

    一行一个整数,表示答案对1e9+7取模后的结果。
    

    示例1

    输入

    复制

    3
    &|^
    

    输出

    复制

    8
    

    说明

    合法的01序列有:
    0001
    0010
    0101
    0110
    1001
    1010
    1100
    1110
    

    DP。设dp[i] [j] [k] 为当前遍历到第i个操作符,此操作符后面的运算数选择j(j为0或者1),得到的结果为k(k为0或1)的数列总数。

    根据三个运算符,很容易就能写出转移方程。

    记得初始化要正确。

    #include <iostream>
    #define mod 1000000007
    using namespace std;
    string s;
    int n;
    int dp[10000005][2][2] = { 0 };//dp[i][j]表示在进行了第i个操作符 当前选择j(j=1 or 0) 得到 k 的数字序列数
    int main()
    {
    	freopen("data.txt", "r", stdin);
    	cin >> n;
    	cin >> s;
    	s = ' ' + s;
    	dp[0][1][1] = dp[0][0][0] = 1;//正确初始化
    	for(int i = 1; i <= n; i++)
    	{
    		if(s[i] == '&')
    		{
    			dp[i][0][0] = (((dp[i - 1][0][0] + dp[i - 1][0][1]) % mod + dp[i - 1][1][0]) % mod + dp[i - 1][1][1]) % mod;
    			dp[i][0][1] = 0;//显然不存在这种情况
    			dp[i][1][0] = (dp[i - 1][1][0] + dp[i - 1][0][0]) % mod;
    			dp[i][1][1] = (dp[i - 1][1][1] + dp[i - 1][0][1]) % mod;
    		}
    		else if(s[i] == '|')
    		{
    			dp[i][0][0] = (dp[i - 1][1][0] + dp[i - 1][0][0]) % mod;
    			dp[i][0][1] = (dp[i - 1][1][1] + dp[i - 1][0][1]) % mod;
    			dp[i][1][0] = 0;//显然不存在这种情况
    			dp[i][1][1] = (((dp[i - 1][0][0] + dp[i - 1][0][1]) % mod + dp[i - 1][1][0]) % mod + dp[i - 1][1][1]) % mod;
    		}
    		else if(s[i] == '^')
    		{
    			dp[i][0][0] = (dp[i - 1][1][0] + dp[i - 1][0][0]) % mod;
    			dp[i][0][1] = (dp[i - 1][1][1] + dp[i - 1][0][1]) % mod;
    			dp[i][1][0] = (dp[i - 1][1][1] + dp[i - 1][0][1]) % mod;
    			dp[i][1][1] = (dp[i - 1][1][0] + dp[i - 1][0][0]) % mod;
    		}
    
    	}
    	// for(int i = 1; i <= n; i++)
    	// {
    	// 	cout << dp[i][0][0] << ' ' << dp[i][0][1] << ' ' << dp[i][1][0] << ' ' << dp[i][1][1] << endl;
    	// }
    	cout << (dp[n][1][1] + dp[n][0][1]) % mod;
    	return 0;
    }
    
  • 相关阅读:
    推荐一款作图工具
    web应用中幂等性的学习
    读书笔记:重构原则
    /usr/bin/ld: cannot find -lc错误原因及解决方法
    ar命令学习
    Linux下C语言编程中库的使用
    idea实战技巧
    intelj idea中除了Find Usage外的另一种查找级联调用的方法
    jenkins构建,拉取不到最新版本代码,报clock of the subversion server appears to be out of sync
    服务器出现大量close_wait,我们来说说到底是怎么回事?(以tomcat为例)
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13902580.html
Copyright © 2011-2022 走看看