• 题面描述

    • 有\(n\)个木块排成一行,从左到右依次编号为\([1,n]\)。你有\(k\)种颜色的油漆,其中第\(i\)种颜色的油漆足够涂\(c_i\)个木块。所有油漆刚好足够涂满所有木块,即\(\sum_{i=1}^k c_i=n\)。相邻两个木块涂相同色显得很难看,所以你希望统计任意两个相邻木块颜色不同的着色方案。
  • 输入格式
    • 第一行为一个正整数\(k\),第二行包含\(k\)个整数\(c_1, c_2, ... , c_k\)。
  • 输出格式
    • 输出一个整数,即方案总数模\(1e9+7\)的结果。
  • 题解
    • 根据题意可写出暴力\(dp\),\(f_{i,5,5,\cdots\,5,x}\)时空复杂度爆炸
    • 但是我们其实并不需要记录每个色有多少个,我们只需要记录当前颜色有\(1,2,3,4,5\)个各有几个,\(f_{i,a_1,a_2,a_3,a_4,a_5,x}\)用记忆化搜索即可
  • 备注
    • 用正常方法做,会有很多冗余状态,不能直接用\(cnt_i\)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll f[16][16][16][16][16][6];
bool use[16][16][16][16][16][6];
int n;
int cnt[6];
ll dp(int a,int b,int c,int d,int e,int x){if (use[a][b][c][d][e][x]) return f[a][b][c][d][e][x];if (a+b+c+d+e==0) return 1;ll ret=0;if (a>0) ret=(ret+(a-(x==2))*dp(a-1,b,c,d,e,1)%mod)%mod;if (b>0) ret=(ret+(b-(x==3))*dp(a+1,b-1,c,d,e,2)%mod)%mod;if (c>0) ret=(ret+(c-(x==4))*dp(a,b+1,c-1,d,e,3)%mod)%mod;if (d>0) ret=(ret+(d-(x==5))*dp(a,b,c+1,d-1,e,4)%mod)%mod;if (e>0) ret=(ret+e*dp(a,b,c,d+1,e-1,5)%mod)%mod;use[a][b][c][d][e][x]=1;return f[a][b][c][d][e][x]=ret%mod;
}
int main(){scanf("%d",&n);for (int i=1;i<=n;i++){int x; scanf("%d",&x);cnt[x]++;}
//  memset(f,-1,sizeof(f));printf("%lld\n",dp(cnt[1],cnt[2],cnt[3],cnt[4],cnt[5],0));return 0;
}
  • 附一个错误的顺序\(dp\)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=76;
int n,cnt[10],tot;
int f[3][16][16][16][16][16][6];
int main(){scanf("%d",&n);for (int i=1;i<=n;i++){int x; scanf("%d",&x);cnt[x]++;tot+=x;}n=tot;f[1][cnt[1]-1][cnt[2]][cnt[3]][cnt[4]][cnt[5]][1]=cnt[1];f[1][cnt[1]+1][cnt[2]-1][cnt[3]][cnt[4]][cnt[5]][2]=cnt[2];f[1][cnt[1]][cnt[2]+1][cnt[3]-1][cnt[4]][cnt[5]][3]=cnt[3];f[1][cnt[1]][cnt[2]][cnt[3]+1][cnt[4]-1][cnt[5]][4]=cnt[4];f[1][cnt[1]][cnt[2]][cnt[3]][cnt[4]+1][cnt[5]-1][5]=cnt[5];for (int i=2;i<=n;i++){for (int j=0;j<=15;j++){for (int k=0;k<=15;k++){for (int l=0;l<=15;l++){for (int m=0;m<=15;m++){for (int r=0;r<=15;r++){for (int x=1;x<=5;x++){for (int y=1;y<=5;y++){int now=i&1; int pre=now^1;if (j>0&&x==1&&x+1==y) f[now][j-1][k][l][m][r][x]+=f[pre][j][k][l][m][r][y]*(j-1);if (j>0&&x==1&&x+1!=y) f[now][j-1][k][l][m][r][x]+=f[pre][j][k][l][m][r][y]*j;if (k>0&&x==2&&x+1==y) f[now][j+1][k-1][l][m][r][x]+=f[pre][j][k][l][m][r][y]*(k-1);if (k>0&&x==2&&x+1!=y) f[now][j+1][k-1][l][m][r][x]+=f[pre][j][k][l][m][r][y]*k;if (l>0&&x==3&&x+1==y) f[now][j][k+1][l-1][m][r][x]+=f[pre][j][k][l][m][r][y]*(l-1);if (l>0&&x==3&&x+1!=y) f[now][j][k+1][l-1][m][r][x]+=f[pre][j][k][l][m][r][y]*l;if (m>0&&x==4&&x+1==y) f[now][j][k][l+1][m-1][r][x]+=f[pre][j][k][l][m][r][y]*(m-1);if (m>0&&x==4&&x+1!=y) f[now][j][k][l+1][m-1][r][x]+=f[pre][j][k][l][m][r][y]*m;if (r>0&&x==5&&x+1==y) f[now][j][k][l][m+1][r-1][x]+=f[pre][j][k][l][m][r][y]*(r-1);if (r>0&&x==5&&x+1!=y) f[now][j][k][l][m+1][r-1][x]+=f[pre][j][k][l][m][r][y]*r;}}}}}}}}int ans=0;for (int i=0;i<=15;i++){for (int j=0;j<=15;j++){for (int k=0;k<=15;k++){for (int l=0;l<=15;l++){for (int m=0;m<=15;m++){for (int x=1;x<=5;x++){ans+=f[n&1][i][j][k][l][m][x];}}}}}}printf("%d\n",ans);return 0;
}

转载于:https://www.cnblogs.com/shjrd-dlb/p/10839250.html

$bzoj1079-SCOI2008$ 着色方案 $dp$相关推荐

  1. bzoj1079: [SCOI2008]着色方案(DP)

    1079: [SCOI2008]着色方案 题目:传送门 题解: DP刚神多年前讲过的一道神题. 二话不说,上来就是一个六维数组:F[i][a][b][c][d][e]//表示上一次涂的颜色是还剩下i次 ...

  2. [BZOJ1079][SCOI2008]着色方案 dp

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2368  Solved: 1428 [Submit][St ...

  3. bzoj1079: [SCOI2008]着色方案

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MB Description 有n个木块排成一行,从左到右依次编号为1~n.你有k ...

  4. BZOJ1079 [SCOI2008]着色方案 记忆化搜索

    1079: [SCOI2008]着色方案 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2826  Solved: 1682 [Submit][St ...

  5. bzoj1079 [SCOI2008]着色方案

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

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

    题目链接 思想 显然我们后面的决策是跟前一步相关的,因此我们可以考虑DP,可以用一个15维的数组来进行转移,但是这样显然回mle,所以我们考虑如何压缩状态,由于1<=Ci<=51 < ...

  7. bzoj 1079 [SCOI2008]着色方案

    bzoj 1079 [SCOI2008]着色方案 Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所 ...

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

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

  9. [SCOI2008]着色方案

    这题也是看了别人题解也才会做的. 题解: 本题用的记忆优化搜索,题目说了给的颜色可以恰好图够所有木块. 题目给了能涂几块木块的颜色一共有几种.因为我们不可以连续图,所以我们把他分开来涂色. 用dp[a ...

  10. bzoj 1079: [SCOI2008]着色方案

    思路:按个数分类dp 1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se se ...

最新文章

  1. C/C++ 语言中表达式的求值
  2. 对 Accordion 组件使用样式
  3. 数学中不可能实现的图形
  4. [iOS Animation]-CALayer 性能优化实例
  5. React开发(106):方法定义 不然弹出框报错
  6. python hello world重复_查找数组中重复的数字-python版
  7. 数据结构 5排序算法
  8. python_文件读写_提取kitti数据集中带时间戳的IMU测量数据
  9. oracle 切换用户操作--or--sys用户密码忘记
  10. oracle regexp提取数字,Oracle中的正则替换【REGEXP
  11. [牛年第一贴 09.2.1] 51CTO 编辑部的那些事儿
  12. Qt Designer简介
  13. Python基础知识——字符串:format() 字符串的格式化
  14. Latex设置每段前的空格数
  15. ventoy集成微PE+优启通;vmware虚拟机如何进入PE系统,ventoy启动盘制作。
  16. 1.GraphPad Prism 8软件安装
  17. 微信小程序四种json配置文件详解
  18. 产品经理(Product Manager)相关英文术语
  19. 解锁scott用户,以及查看oracle中scott用户所拥有的四张表。
  20. ROS源代码阅读(9)——DWA算法

热门文章

  1. Reporting Services 空白页面
  2. 设计模式----原型模式(C++实现)
  3. Mac下Vmware Fusion配置虚拟机虚拟网卡并配置CENTOS上网
  4. 8.4完成服务(Completion Services)
  5. 【渝粤教育】国家开放大学2018年春季 0266-21T设计构成 参考试题
  6. 【渝粤教育】国家开放大学2018年春季 0001-21T入学教育与终身学习指引 参考试题
  7. [渝粤教育] 西南科技大学 公共关系学 在线考试复习资料
  8. 【Python实例第16讲】特征集聚
  9. 【RLchina第二讲】汪军老师推荐的强化学习理论学习资料
  10. 高品味男人:分寸与克制