zoukankan      html  css  js  c++  java
  • BZOJ 1079: [SCOI2008]着色方案( dp )

    dp...或者说是记忆化搜索吧....

    注意到 1 <= c_i <= 5 , 虽然 1 <= k <= 15 , 但是我们可以把剩下油漆数相同的看做等价类 

    dp( a , b , c , d , e , p ) 表示剩下油漆数为 1 的油漆有 a 种 , 剩下油漆数为 2 的油漆有 b 种 …… p 表示上一个木块是用了哪一种油漆着色 . 然后转移就看 code 吧...

    --------------------------------------------------------------------

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
     
    #define clr( x , c ) memset( x , c , sizeof( x ) )
    #define rep( i , n ) for( int i = 0 ; i < n ; ++i )
    #define mod( x ) ( ( x ) %= MOD )
     
    using namespace std;
     
    const int MOD = 1e9 + 7;
    const int maxn = 17;
     
    int h[ maxn ][ maxn ][ maxn ][ maxn ][ maxn ][ maxn ];
     
    int dfs( int a , int b , int c , int d , int e , int p ) {
    int &ans = h[ a ][ b ][ c ][ d ][ e ][ p ];
    if( ans ) return ans;
    ans = 0;
    if( a ) mod( ans += 1LL * ( a - ( p == 2 ) ) * dfs( a - 1 , b , c , d , e , 1 ) % MOD );
    if( b ) mod( ans += 1LL * ( b - ( p == 3 ) ) * dfs( a + 1 , b - 1 , c , d , e , 2 ) % MOD );
    if( c ) mod( ans += 1LL * ( c - ( p == 4 ) ) * dfs( a , b + 1 , c - 1 , d , e , 3 ) % MOD );
    if( d ) mod( ans += 1LL * ( d - ( p == 5 ) ) * dfs( a , b , c + 1 , d - 1 , e , 4 ) % MOD );
    if( e ) mod( ans += 1LL * e * dfs( a , b , c , d + 1 , e - 1 , 5 ) % MOD );
    return ans;
    }
     
    int main() {
    freopen( "test.in" , "r" , stdin );
    clr( h , 0 );
    rep( i , 6 ) h[ 0 ][ 0 ][ 0 ][ 0 ][ 0 ][ i ] = 1;
    int k , t[ 6 ] = { 0 , 0 , 0 , 0 , 0 , 0 };
    cin >> k;
    while( k-- ) {
    int v;
    scanf( "%d" , &v );
    t[ v ]++;
    }
    cout << dfs( t[ 1 ] , t[ 2 ] , t[ 3 ] , t[ 4 ] , t[ 5 ] , 0 ) << " ";
        return 0; 

      

    -------------------------------------------------------------------- 

    1079: [SCOI2008]着色方案

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1100  Solved: 697
    [Submit][Status][Discuss]

    Description

    有n个木块排成一行,从左到右依次编号为1~n。你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块。所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n。相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案。

    Input

    第一行为一个正整数k,第二行包含k个整数c1, c2, ... , ck。

    Output

    输出一个整数,即方案总数模1,000,000,007的结果。

    Sample Input

    3
    1 2 3

    Sample Output

    10

    HINT

     100%的数据满足:1 <= k <= 15, 1 <= ci <= 5

    Source

  • 相关阅读:
    nodejs创建路由
    node,js 使用express 生成站点的命令
    Ajax异步同步原理
    jquery问题总结
    JS正则表达式
    幻灯片缓冲效果
    转:offsetParent的理解
    微信小程序左右滑动切换页面示例代码--转载
    python正则表达式
    Django笔记(番外):虚拟环境
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4642579.html
Copyright © 2011-2022 走看看