HDU 2583 permutation

原题链接

题意大概就是求n的全排列中,用大于小于号连接,其中小于号有k个的情况有多少种。注意,ac代码是%2009,不是2007

显然n的全排列有n!个,考虑下dp算法

状态转移是DP(n,k)=dp(n-1,k)*(k+1)+dp(n-1)(k-1)*(n-k)

n代表考虑n个数字的状态,k代表小于号的个数。

先作特殊情况,序列1 2 3 4 5 6,一共5个小于号,如果我要加入数字7,那么我有7种加法,并且只有一种加法会使小于号+1.

序列a1 a2 a3 a4 a5 ……a(n-1),一共有n-1个数字,有k个小于号,那么我加入an有n种加法,其中会使小于号+1的有n-k种(就是加在大于号的位置上),其他的k+1种不会改变小于号的个数。

#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<algorithm>
#include<math.h>
#include<iostream>
using namespace std;
#define LL long long
#define INF 99999999
int dp[111][111];
main()
{
  
  int n,k,i,j;
    for(i=0;i<=100;i++)
    {
        dp[i][0]=1;
        dp[0][i]=0;
    }
  for(i=1;i<=100;i++)
    for(j=1;j<=100;j++)
       dp[i][j]=dp[i-1][j]*(j+1)+dp[i-1][j-1]*(i-j),dp[i][j]=dp[i][j]%2009;
  while(scanf("%d %d",&n,&k)!=EOF)
    printf("%d\n",dp[n][k]);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值