http://www.lydsy.com/JudgeOnline/problem.php?id=1079

只能想到5^15的做法。。。。。。。。。。。。。。。。。。。。。。。。。。。果然我太弱。

其实应该是没利用好题目的信息,ci<=5!

那么我们可以将颜色所剩余的格子看做一种等价类!

即,设状态f[a,b,c,d,e]表示还剩1个格子的颜色有a种,剩2个格子的颜色有b种...依次类推,且当前正在放第n-1*a-2*b-3*c-4*d-5*e+1格子。那么转移就是

f[a,b,c,d,e]=a*f[a-1,b,c,d,e]+b*f[a+1,b-1,c,d,e]+c*f[a,b+1,c-1,d,e]+...+e*f[a,b,c,d+1,e-1]

可是我们发现没有考虑相邻的情况?没事!我们可以加一维!

我们再加一维,表示上一次用的颜色是等价类last,那么这一次计算的时候因为不能相邻,那么这个这一次放last-1的颜色时要少一个,所以是a-1或b-1或....或e-1然后再乘上后边的f。

那么转移就变成了:

f[a,b,c,d,e,last]=(a-(last==2))*f[a-1,b,c,d,e]+(b-(last==3))*f[a+1,b-1,c,d,e]+(c-(last==4))*f[a,b+1,c-1,d,e]+...+(e-(last==6))*f[a,b,c,d+1,e-1]

而last==6无意义,可以去掉。

那么记忆化搜索即可。

真是一道好题!

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const ll MD=1000000007;
ll f[17][17][17][17][17][6];
ll dp(int a, int b, int c, int d, int e, int last) {
if((a|b|c|d|e)==0) return 1;
if(f[a][b][c][d][e][last]) return f[a][b][c][d][e][last];
ll ret=0;
if(a) ret+=dp(a-1, b, c, d, e, 1)*(a-(last==2));
if(b) ret+=dp(a+1, b-1, c, d, e, 2)*(b-(last==3));
if(c) ret+=dp(a, b+1, c-1, d, e, 3)*(c-(last==4));
if(d) ret+=dp(a, b, c+1, d-1, e, 4)*(d-(last==5));
if(e) ret+=dp(a, b, c, d+1, e-1, 5)*e;
return f[a][b][c][d][e][last]=ret%MD;
} int a[6];
int main() {
int n=getint();
for1(i, 1, n) a[getint()]++;
printf("%lld\n", dp(a[1], a[2], a[3], a[4], a[5], 0));
return 0;
}

  


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

【BZOJ】1079: [SCOI2008]着色方案(dp+特殊的技巧)的更多相关文章

  1. bzoj 1079: [SCOI2008]着色方案 DP

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 803  Solved: 512[Submit][Status ...

  2. BZOJ 1079: [SCOI2008]着色方案 记忆化搜索

    1079: [SCOI2008]着色方案 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  3. BZOJ 1079: [SCOI2008]着色方案(巧妙的dp)

    BZOJ 1079: [SCOI2008]着色方案(巧妙的dp) 题意:有\(n\)个木块排成一行,从左到右依次编号为\(1\)~\(n\).你有\(k\)种颜色的油漆,其中第\(i\)种颜色的油漆足 ...

  4. BZOJ 1079 [SCOI2008]着色方案

    http://www.lydsy.com/JudgeOnline/problem.php?id=1079 思路:如果把每种油漆看成一种状态,O(5^15)不行 DP[a][b][c][d][e][f] ...

  5. bzoj 1079: [SCOI2008]着色方案【记忆化搜索】

    本来打算把每个颜色剩下的压起来存map来记忆化,写一半发现自己zz了 考虑当前都能涂x次的油漆本质是一样的. 直接存五个变量分别是剩下12345个格子的油漆数,然后直接开数组把这个和步数存起来,记忆化 ...

  6. BZOJ1079:[SCOI2008]着色方案(DP)

    Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个 ...

  7. 1079: [SCOI2008]着色方案

    链接 思路 首先是dp,如果直接用每个种颜色的剩余个数做状态的话,复杂度为5^15. 由于c<=5,所以用剩余数量的颜色的种类数做状态:f[a][b][c][d][e][last]表示剩余数量为 ...

  8. bzoj1079: [SCOI2008]着色方案

    ci<=5直接想到的就是5维dp了...dp方程YY起来很好玩...写成记忆化搜索比较容易 #include<cstdio> #include<cstring> #inc ...

  9. [SCOI2008]着色方案

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2228  Solved: 1353[Submit][Stat ...

随机推荐

  1. swift -类的定义及使用

    // // main.swift // ClassDemo-06 // import Foundation println("Hello, World!") //类的定义 Pers ...

  2. 在MVC的cshtml视图页获取默认路由下的ID值的方法

    <a href="/user/resume/index/11"> <span class="title bold">我的 @Reques ...

  3. Android应用开发相关下载资源(2014/12/14更新)

    官方终于发布了Android Studio正式版,Android Studio将会成为推荐使用的主要Android开发工具. (1)Android SDK (Android SDK主安装包,包含SDK ...

  4. Spring+Struts+Hibernate 简介(转)

    http://blog.csdn.net/slnqnd/article/details/1772910/ Struts2.0 +Hibernate 3.2 +Spring 2.0 一.         ...

  5. php后台“爬虫”模拟登录第三方系统

    http://blog.csdn.net/liu_c_y/article/details/49956679 http://www.php100.com/html/webkaifa/PHP/PHPyin ...

  6. PHP-Resque 简介

    转载于:http://blog.hsatac.net/2012/01/php-resque-introduction/ Resque 是 Github 基於 Redis 开发的 background ...

  7. 用PL/pgSQL写postgreSQL的存储过程[转]

    http://blog.chinaunix.net/uid-7591044-id-1742967.html 今天学会了用 PL/pgSQL 写 postgreSQL 的存储过程,网上资料实在少得可怜, ...

  8. ISP图像质量调节介绍

    ISP(Image Signal Processor),即图像处理,主要作用是对前端图像传感器输出的信号做后期处理,主要功能有线性纠正.噪声去除.坏点去除.内插.白平衡.自己主动曝光控制等.依赖于IS ...

  9. numpy 文件存取 npy、npz

    转处:http://blog.csdn.net/pipisorry/article/details/39088003 NumPy提供了多种文件操作函数方便我们存取数组内容. 文件存取的格式:二进制和文 ...

  10. 停掉一台服务器,Nginx响应慢(转载)

    测试发现的问题及解决办法 1.当后端两台IIS应用服务器都正常时,访问速度非常快,查看日志,原来一个请求,是后端两台服务器同时响应的; 2.为了模仿故障测试,停掉一台IIS应用服务器,这时再访问,请求 ...