BZOJ 1079: [SCOI2008]着色方案( dp )

本文介绍了一种解决SCOI2008着色方案问题的方法,使用了记忆化搜索策略。问题要求统计给定条件下,使得相邻木块颜色不同的着色方案总数。通过将剩余相同油漆数量归类,利用递归函数进行状态转移。

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 ) << "\n";
    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

 

转载于:https://www.cnblogs.com/JSZX11556/p/4642579.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值