zoukankan      html  css  js  c++  java
  • 着色方案(动态规划+记忆化搜索)

    题目链接https://www.lydsy.com/JudgeOnline/problem.php?id=1079

    AC代码:

     1 /*
     2     直接状态压缩是显然是不可行的,我们考虑如果没有相邻颜色不相同的限制的话,
     3     如果两种油漆能染的木块数目相同,我们就可以认为两种油漆无差别。
     4     设dp[a1][a2][a3][a4][a5]为能染1个木块的油漆有a1种……的方案数。
     5     但是有相邻颜色的限制,如果上一次用了颜色数为k的油漆,
     6     那么这一次有一种颜色数为k-1的油漆就不能用了,转移的时候注意一下。
     7 */
     8 # include <iostream>
     9 # include <stdio.h>
    10 # include <string.h>
    11 # include <algorithm>
    12 # include <bitset>
    13 # include <ctime>
    14 # include <climits>
    15 # include <set>
    16 # include <map>
    17 # include <cctype>
    18 # include <cmath>
    19 # include <deque>
    20 # include <queue>
    21 # include <stack>
    22 # include <vector>
    23 # include <functional>
    24 using namespace std;
    25 
    26 typedef long long LL;
    27 const int maxn=16;
    28 const LL mod=1e9+7;
    29 int n, x[16];
    30 LL f[16][16][16][16][16][6];///f数组表示当前有能涂1次的油漆a个,能涂2次的b个....前一个涂的是还能涂k次的油漆
    31 bool dp[16][16][16][16][16][6];
    32 
    33 LL Dp(int a, int b, int c, int d, int e, int k)
    34 {
    35     LL t=0;
    36     if( dp[a][b][c][d][e][k] )
    37         return f[a][b][c][d][e][k];
    38     if( a+b+c+d+e==0 )
    39         return 1;
    40     if( a )
    41         t = t+(a-(k==2))*Dp(a-1, b, c, d, e, 1);///一种可以染1个方块的颜色,变成了可以染0个方块(所以a-1),如果上一次用了颜色数为2的油漆, 那么这一次有一种颜色数为1的油漆就不能用了
    42     if( b )
    43         t = t+(b-(k==3))*Dp(a+1, b-1, c, d, e, 2);///一种可以染2个方块的颜色,变成了可以染1个方块(所以b-1, a+1),如果上一次用了颜色数为3的油漆, 那么这一次有一种颜色数为2的油漆就不能用了
    44     if( c )
    45         t = t+(c-(k==4))*Dp(a, b+1, c-1, d, e, 3);///一种可以染3个方块的颜色,变成了可以染2个方块(所以c-1, b+1),如果上一次用了颜色数为4的油漆, 那么这一次有一种颜色数为3的油漆就不能用了
    46     if( d )
    47         t = t+(d-(k==5))*Dp(a, b, c+1, d-1, e, 4);///一种可以染4个方块的颜色,变成了可以染3个方块(所以d-1, c+1),如果上一次用了颜色数为5的油漆, 那么这一次有一种颜色数为4的油漆就不能用了
    48     if( e )
    49         t = t+e*Dp(a, b, c, d+1, e-1, 5);///一种可以染5个方块的颜色,变成了可以染4个方块(所以e-1, d+1),如果这一次用可以染5个方块的颜色,因为题目有条件1 <= ci <= 5,所以说明他之前一定没用过
    50     dp[a][b][c][d][e][k] = 1;
    51     return f[a][b][c][d][e][k] = (t%mod);
    52 }
    53 
    54 int main()
    55 {
    56     scanf("%d", &n);
    57     for(int i=1; i<=n; i++)
    58     {
    59         int y;
    60         scanf("%d", &y);
    61         x[y]++;
    62     }
    63     printf("%lld
    ", Dp(x[1], x[2], x[3], x[4], x[5], 0));
    64     return 0;
    65 }
  • 相关阅读:
    Ubuntu 拦截并监听 power button 的关机消息
    Android 电池管理系统架构总结 Android power and battery management architecture summaries
    Linux 内核代码风格
    Linux 内核工作队列之work_struct 学习总结
    微信小程序 登录流程规范解读
    微信小程序监听input输入并取值
    koala 编译scss不支持中文(包括中文注释),解决方案如下
    阻止冒泡和阻止默认事件的兼容写法
    使用setTimeout实现setInterval
    css实现视差滚动效果
  • 原文地址:https://www.cnblogs.com/wsy107316/p/11330732.html
Copyright © 2011-2022 走看看