当前位置: 首页 > article >正文

HDU Sit sit sit (区间DP+组合数)

题目大意:有 n 张椅子,n 个人,所有人都可以按照任意顺序坐在任意一张椅子上,但是同时满足这三种情况的椅子不能坐:
1.椅子上有左右两张相邻的椅子。
2.左右相邻的椅子不是空的。
3.左右相邻的椅子颜色不同。
如果当前学生没有椅子可以坐,他就会离开。

问一共有几种坐法?

思路:区间dp+组合数

dp[i][j] : 记录在 i ~ j 之间满足题目要求的排列数。

C[i][j] : (组合数)在 i 个人中挑选 j 个人。

在长度为 1 的时候,排列数肯定为 1,在长度为 2的时候排列数肯定为 2,当长度大于等于 3 的时候就要开始分裂类讨论了。第一种情况最有一个人坐在两边的情况,第二种情况最后一个人不坐在两边的情况。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
const int N=1e2+5;
const int mod=1e9+7;
int a[N],dp[N][N],C[N][N];
signed main(){
	for(int i=0;i<=101;i++){//杨辉三角求组合数 
		C[i][0]=C[i][i]=1;
		for(int j=1;j<i;j++){
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
		}
	}
	int n;
	while(cin >> n){
		for(int i=1;i<=n;i++){
			cin >> a[i];
			dp[i][i]=1;//长度为 1 ,有一种排列方式 
			if(i+1<=n) dp[i][i+1]=2; // 长度为 2,有两种排列方式 
		}
		for(int len=2;len<n;len++){
			for(int i=1;i<=n;i++){
				int j=i+len;
				if(j>n) break;
				dp[i][j]=(dp[i+1][j]+dp[i][j-1])%mod;//最后一个人坐在两边的情况 
				for(int k=i+1;k<j;k++){
					if(a[k-1]==a[k+1]) dp[i][j]=(dp[i][j]+dp[i][k-1]*dp[k+1][j]%mod*C[j-i][k-i]%mod)%mod;//最后一个人坐在第 k 个位置且满足题目要求的情况 
					//j-i就是当前长度 len( k 除外),k-i就是在 k 之前的位置的个数,C[j-i][k-i]就是在(j-i)个人里挑(k-i)个人坐到 k 前面的那几个位子去 
				}
			}
		}
		cout << dp[1][n] << endl;
	}
	return 0;
}


http://www.kler.cn/news/334967.html

相关文章:

  • 打造自己的RAG解析大模型:Windows部署OCR服务(可商业应用)
  • springboot网上商城源码分享
  • Chromium 中JavaScript Console API接口c++代码实现
  • Goland 设置GOROOT报错 The selected directory is not a valid home for Go SDK
  • C语言:预编译过程的剖析
  • npm、yarn、pnpm之间的区别
  • 构建数字化生态平台,开启企业新未来
  • 冯诺依曼体系|操作系统
  • 服务器租用与托管注意事项有哪些?
  • [Day 84] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
  • 【包教包会】2D图片实现3D透视效果(支持3.x、支持原生、可合批)
  • ElasticSearch备考 -- Multi match
  • 代码随想录算法训练营第35天|1049.最后一块石头的重量II、494.目标和、474.一和零
  • 词嵌入(Word Embedding)之Word2Vec、GloVe、FastText
  • Hive数仓操作(十七)
  • 趣味SQL | 从围棋收官到秦楚大战的数据库SQL实现(下)
  • Linux高级编程_29_信号
  • 【NIO基础】NIO(非阻塞 I/O)和 IO(传统 I/O)的区别,以及 NIO 的三大组件详解
  • EXCEL_光标百分比
  • 计算机网络:物理层 —— 物理层下的传输媒体