首页 > 其他分享 >51nod 1296 有限制的排列

51nod 1296 有限制的排列

时间:2024-09-09 14:48:14浏览次数:8  
标签:排列 const 51nod long int 1296 dp

题目链接

学习链接

设状态 \(dp[i][j]\) 表示整数 \([1,i]\) 满足要求的排列中,最后一个数选 \(j\) 的排列数。

开一个数组记录他的状态:

image

把前面已选好的序列中大于等于 \(j\) 的数都加一后再把 \(j\) 加到后面。

image

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
const int N=5e3+10;
int n,a,b,x;

int p[N];
int dp[N][N],s[N];

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>a>>b;
    
    for(int i=1;i<=a;i++){
    	cin>>x;
    	++x;
    	p[x]=1;p[x+1]=2;
	}
	
	for(int i=1;i<=b;i++){
		cin>>x;
		++x;
		p[x]=2;
		p[x+1]=1;
	}
    dp[1][1]=s[1]=1;
    
    for(int i=2;i<=n;i++){
    	for(int j=1;j<=i;j++){
    		if(p[i]==0){
    			dp[i][j]+=s[i-1];
    			dp[i][j]%=mod;
			}
			else if(p[i]==1){
				dp[i][j]+=(s[i-1]-s[j-1]+mod)%mod;
				dp[i][j]%=mod;
			}
			else{
				dp[i][j]+=s[j-1];
				dp[i][j]%=mod;
			}
		}
		for(int j=1;j<=i;j++){
			s[j]=(s[j-1]+dp[i][j])%mod;
		}
	}
    ll ans=0;
    for(int i=1;i<=n;i++){
    	ans+=dp[n][i];
    	ans%=mod;
	}
    cout<<ans;
    return 0;
}

标签:排列,const,51nod,long,int,1296,dp
From: https://www.cnblogs.com/sadlin/p/18404542

相关文章

  • 51nod 1050 循环数组最大子段和
    51nod1050循环数组最大子段和虽然是板子题,两种做法,我们先写一种,另一个咕咕。因为是循环,所以分为两种,中间的和两边的,中间的直接dp求最大,两边的转化一下就是总的数字和减去中间的最小数字和。#include<bits/stdc++.h>usingnamespacestd;#definelllonglonglla[500005]......
  • 51nod 1791 合法括号子段
    51nod1791原题链接因为在括号串固定的情况下,括号的匹配是固定不变的。所以对左括号进行匹配,p[i]表示与i这个括号相匹配的括号的位置,易得到dp方程ans[i]=ans[p[i]+1]+1,然后再从后先前一遍求和即可。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconst......
  • 51nod 石子分配
    可以发现步数限制把数轴变为了环。环之间不可以交换,环内相邻两点可以交换,然后我们只需要对每个环操作,最后累加。对于环上的每个石子堆,我们需要将其石子数调整到均值\(avg\)。因此,我们首先计算每个堆石子相对于\(avg\)的偏差,即\(nowa[i]-avg\)。因为相邻节点不一定能凑齐......
  • python 实现第k个字典排列算法
    第k个字典排列算法介绍"第k个字典排列"算法通常指的是在给定的字符集合(例如,字符串中的字符)中,找到所有可能排列的第k个排列。这个问题可以通过多种方法解决,但一个常见且高效的方法是使用“下一个排列”算法的变种,或称为“第k个排列”的直接算法。方法一:使用“下一个排列”......
  • 代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II
    代码随想录刷题day25丨491.递增子序列,46.全排列,47.全排列II1.题目1.1递增子序列题目链接:491.非递减子序列-力扣(LeetCode)视频讲解:回溯算法精讲,树层去重与树枝去重|LeetCode:491.递增子序列_哔哩哔哩_bilibili文档讲解:https://programmercarl.com/0491.%E9%80......
  • 排列组合(一)
    目录排列组合示例题目题目答案与解析开学后的第一篇博文,太不容易了。。。。。今后我会做更多关于我要打的比赛要考的一些知识,也方便自己回顾。最后有很多例题给大家练练手哦。前言排列组合是CCF(中国计算机学会(ChinaComputerFederation),大家可以去看看它的官网:http......
  • 51nod 1110 距离之和最小
    51nod1110距离之和最小考虑贪心取中位数,因为中位数到左边的点和右边的点的个数相同,更合理,权值的话可以转化为一个单点,然后没了。#include<bits/stdc++.h>usingnamespacestd;#definelllonglongintn;structss{ llx,w;}a[100005];boolcmp(ssg,ssh){ return......
  • 51nod 1383 整数分解为2的幂
    整数分解为2的幂这题非常厉害,建议认真看下去虽然我讲的也不好。首先肯定先想到的是多重背包,可以把每个次幂当作物品,然后套板子。但是这题有\(O(n)\)复杂度的做法,我们想如果一个数\(i\)是奇数,那他只能由\((i-1)+1\)转化过来(2的幂次只有1是奇数),那方案数就是\(i-1\)的方案......
  • 51nod 2180 争渡
    争渡原题链接常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。——李清照《如梦令·常记溪亭日暮》给出线段上界和下界,要在严格递增地在区间内选数,问到最后一条线段的方案数。见上图,第\(i\)条线段\(j\)点的方案数为\(i-1\)条线段的\(j-1\)......
  • 51nod 2842 城际旅行
    原题链接这题因为要求满足t时间内,所以用dp,不过我们的状态比较特殊,\(dp[i][j]\)表示到\(i\)点时经过\(j\)个点的最短时间,因为题目为DAG所以要用拓扑排序,每到一个点,枚举所有出边,更新出点的状态\(f[v][j+1]=min(f[v][j+1],f[u][j])\),最后的答案就是所有\(f[t][j]\let......