hdu 5151 Sit sit sit

http://acm.hdu.edu.cn/showproblem.php?pid=5151

题意:一共有N个椅子,然后有N个学生依次去坐,满足下面三个条件不能坐上去,1:这个椅子旁边有左椅子也有右椅子,2:椅子旁边都有人坐了,3:椅子旁边的椅子颜色不一样。

问如果所有人都坐上去有多少情况。

dp[i][j] 表示区间[i,j]满足的情况数。 这道题是一道区间dp。把一个很大的区间化成多个很小的区间处理。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define mod 1000000007
 5 #define ll long long
 6 using namespace std;
 7
 8 int n;
 9 int a[200];
10 ll c[200][200];
11 ll dp[200][200];
12
13 void inti()
14 {
15     for(int i=0; i<=101; i++)
16     {
17         c[i][0]=1;
18         for(int j=1; j<=i; j++)
19         {
20             c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
21         }
22     }
23 }
24
25 ll get_num(int x,int y)
26 {
27     if(x>y) return 0;
28     if(dp[x][y]) return dp[x][y];
29     if(x==y) return dp[x][y]=1;
30     ll ans=0;
31     for(int i=x+1; i<y; i++)
32     {
33         if(a[i-1]!=a[i+1]) continue;
34         ans+=get_num(x,i-1)*get_num(i+1,y)%mod*c[y-x][i-x]%mod;
35         ans%=mod;
36     }
37     ans+=get_num(x+1,y);
38     ans%=mod;
39     ans+=get_num(x,y-1);
40     ans%=mod;
41     dp[x][y]=ans;
42     return dp[x][y];
43 }
44
45 int main()
46 {
47     inti();
48     while(scanf("%d",&n)!=EOF)
49     {
50         memset(dp,0,sizeof(dp));
51         for(int i=1; i<=n; i++)
52         {
53             scanf("%d",&a[i]);
54         }
55         printf("%lld\n",get_num(1,n));
56     }
57     return 0;
58 }

时间: 2024-12-28 08:45:46

hdu 5151 Sit sit sit的相关文章

hdu 5151 Sit sit sit(DP)

题目链接:hdu 5151 Sit sit sit 区间dp,dp[i][j]表示从i到j的方案数,每次枚举i~j之间放最大值的位置,左右颜色不同的位置不能放最大值. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 105; typedef long long ll; const ll mod = 1e9+7; int N, v

hdu 5151 Sit sit sit(区间dp+排列组合)

题目链接:hdu 5151 Sit sit sit 题意: 一共有并排N个椅子, N个学生依次去坐,同时满足3个条件就不能坐下去: 1,该椅子不在最左,不在最右. 2,该椅子左右都有人坐了. 3,左右的椅子不同颜色.求最后N个人都能坐下去,有多少不同的情况. 题解: 考虑区间dp,dp[i][j] = sum(dp[i][k-1] * dp[k+1][j] * c[j - i][k - i])其中满足(v[k-1]==v[k+1]) 表示i到j区间最后来坐k位置,乘组合是因为合并这两段区间的时候

HDU 5151 Sit sit sit(区间DP)

HDU 5151 Sit sit sit 题目链接 区间DP+组合计数问题,转移方程为,每次选当前区间最后一个放的位置,然后乘上组合数C[区间长度][左区间长度] 代码: #include <cstdio> #include <cstring> typedef long long ll; const ll MOD = 1000000007; const int N = 105; int n, a[N]; ll dp[N][N], C[N][N]; int main() { C[1]

HDU 5151 Sit sit sit 区间dp

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5151 题解: 有n个椅子,编号为1到n. 现在有n个同学,编号为1到n,从第一个同学开始选择要坐的位子,并且这个同学不能坐同时满足下面三个条件的椅子. 1.左右都有相邻的位子 2.左右相邻的位子都是空的. 3.左右两边的位子颜色不同. 问总共有多少种坐法. 题解: dp[i][j]表示坐满编号为i到j的椅子的类数. 现在第一个开始坐的人选择的是第t个位子,则dp[i][j]+=dp[i][t-1]

(记忆化搜索) hdu 5151

Sit sit sit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 238    Accepted Submission(s): 114 Problem Description There are N chairs in a row and and no one on the chairs.Each chair is blue or

HDU 5151 Dire Wolf

题目链接 有n匹狼排成一队,每杀死一头狼会受到这头狼的主要攻击力与它左右两边的狼的辅助攻击力,问最少受到的伤害 枚举每个区间最后被杀死的狼 #include <cstdio> #include <iostream> using namespace std; typedef long long ll; const int inf=1000000000; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'

【HDU】5151 Sit Sit Sit(区间DP+排列组合)

题目大意:可以查阅网站的中文翻译,就不说了,是第24场Best Coder 思路: 这道这道区间DP,我也开始觉得其实区间DP是一种应用型的思想,做这类题目一个重要的点是在于题目情景的把握,这道题的一个情景就是数学的排列组合问题. 首先应用根据小区间推出大区间的思路,我们可以先固定一个位置k,k位置是最后做的位置,那么我们要算出在这种情况下符合的方法数,假如k是头或者尾,那不用说, 此时的方法为dp[i+1][j]或者是dp[i][j-1]; 假如k是有邻居的,那我们就要考虑邻居的颜色,如果颜色

hdu 5150 Sit sit sit

http://acm.hdu.edu.cn/showproblem.php?pid=5151 直接判断是不是素数,然后再注意1就行. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int n; 7 int a[1001]; 8 bool f[1001]; 9 10 void Get_prime() 11 { 12 f[1]=true;

HDU 5151Sit sit sit

一道区间DP题,某次BestCoder的B题,想了很久没想出来. 题目描述:一共有并排N个椅子, N个学生依次去坐,同时满足3个条件就不能坐下去:1,该椅子不在最左,不在最右,2,该椅子左右都有人坐了,3,左右的椅子不同颜色 求最后N个人都能坐下去,有多少不同的情况. 题解:dp[i][j]表示排完区间[i,j]的种类数,(看别人题解时没想明白,人是按顺序先后决定坐的位置,即在区间[i,j]内座位的先后序.当[i,j]->[1,n]时,dp的种类数不就是n个人按顺序先后决定坐的位置的种类) 转移