zoukankan      html  css  js  c++  java
  • Iroha and Haiku II

    标签: 状态压缩DP


    题目描述

    Haiku is a short form of Japanese poetry. A Haiku consists of three phrases with 5, 7 and 5 syllables, in this order.
    Iroha is looking for X,Y,Z-Haiku (defined below) in integer sequences.
    Consider all integer sequences of length N whose elements are between 1 and 10, inclusive. Out of those 10N sequences, how many contain an X,Y,Z-Haiku?
    Here, an integer sequence a0,a1,…,aN−1 is said to contain an X,Y,Z-Haiku if and only if there exist four indices x,y,z,w(0≤x<y<z<w≤N) such that all of the following are satisfied:
    ax+ax+1+…+ay−1=X
    ay+ay+1+…+az−1=Y
    az+az+1+…+aw−1=Z
    Since the answer can be extremely large, print the number modulo 109+7.

    Constraints

    3≤N≤40
    1≤X≤5
    1≤Y≤7
    1≤Z≤5

    输入

    The input is given from Standard Input in the following format:
    N X Y Z

    输出

    Print the number of the sequences that contain an X,Y,Z-Haiku, modulo 109+7.

    样例输入

    3 5 7 5

    样例输出

    1

    提示

    Here, the only sequence that contains a 5,7,5-Haiku is [5,7,5].

    分析

    • 用dp[i][j]来表示,长度为i的数组,最后几个数字的状态为j,且这个数组中不存在连续的一些数的和为X,Y,Z的方法数.
    • 状态j是这么定义的,把数组中的元素的二进制表示按照顺序串联起来,取后X+Y+Z位
    • 如果倒数第Z位,倒数第Y+Z位,倒数第X+Y+Z位都是1,那么就满足了题目中所说的条件.

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll MOD=1e9+7;
    int n,a,b,c;
    ll dp[42][1<<17];
    int main(int argc, char const *argv[])
    {
        scanf("%d%d%d%d", &n,&a,&b,&c);
        dp[0][0]=1;
        int base=(1<<(c-1))+(1<<(b+c-1))+(1<<(a+b+c-1));
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < (1<<(a+b+c)); ++j)
            {
                for (int k = 0; k < 10; ++k)
                {
                    int x=(j<<(k+1))+(1<<k);
                    x&=((1<<(a+b+c))-1);
                    if((x&base)!=base){
                        dp[i+1][x]+=dp[i][j];
                        dp[i+1][x]%=MOD;
                    }
                }
            }
        }
        ll ans=1;
        for (int i = 0; i < n; ++i)
        {
            ans=ans*10%MOD;
        }
        for (int i = 0; i < (1<<(a+b+c)); ++i)
        {
            ans=(ans-dp[n][i])%MOD;
        }
        ans=(ans+MOD)%MOD;
        printf("%lld
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    从零开始搭建系统1.2——Nginx安装及配置
    从零开始搭建系统1.1——CentOs安装
    从零开始搭框架——系统架构
    从零开始搭建系统——前言
    PHP语法入门以及变量
    用PHP写出计算器
    PHP常量以及基本数据类型
    PHP入门了解
    php中搭建Web服务器和服务器配置
    JS中for,for...in,for...of以及foreach循环的用法
  • 原文地址:https://www.cnblogs.com/sciorz/p/9058610.html
Copyright © 2011-2022 走看看