zoukankan      html  css  js  c++  java
  • Codeforces757D Felicity's Big Secret Revealed

    真·失踪人口回归。

    我来证明我没有退役。

    Description

    给定一个长度为 (n(nle 75))(01) 串。将 (01) 串用 (m) 条竖线划分为 (m + 1) 个部分,将两条竖线之间的 (01) 串转为十进制数。若这些数的最大值为 (MAX) 且取值范围为 ([1,MAX]) 且包括了 ([1,MAX]) 中的所有数,则为一次有效的 (m) 切割。定义 (m) 切割的方案数为 (f(m)) 。求 $$sum_{k=2}^{n+1}f(k)$$

    Solution

    因为 (1)(20) 的二进制长度相加正好为 (74) ,故 (MAX) 最大为 (20)

    考虑状压。(dp[i][j]) 表示在 (i-1)(i) 之间有一条竖线,在之前的划分中出现的数的集合为 (j) 的方案数。

    转移见代码。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define N 100
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    
    const int P = 1e9+7;
    int n, num[N][N], dp[N][(1 << 20) + 5];
    char s[N];
    
    int main() {
    	scanf("%d%s", &n, s + 1);
    	rep(i, 1, n) { int k = 0; rep(j, i, n) if ((k = (k << 1) + s[j] - '0') > 20) break; else num[i][j] = k; }
    	rep(i, 1, n) {
    		dp[i][0] = 1;
    		rep(j, 0, (1 << 20) - 1) if (dp[i][j]) rep(k, i, n) if (num[i][k]) (dp[k + 1][j | (1 << num[i][k] - 1)] += dp[i][j]) %= P;
    	}
    	int ans = 0; rep(i, 1, n + 1) rep(j, 1, 20) (ans += dp[i][(1 << j) - 1]) %= P;
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    JAVA web数据库登录界面
    JAVA web之相关名词大调查
    继承与多态课后
    第六周课后作业 02
    凯撒密文问题
    定义一个类,使用静态和构造随时知道定义了几个变量(第五周课后01)
    NAIPC2018
    [学习笔记]网络流
    Rikka with Prefix Sum
    Traffic Network in Numazu
  • 原文地址:https://www.cnblogs.com/aziint/p/9098038.html
Copyright © 2011-2022 走看看