zoukankan      html  css  js  c++  java
  • 水题大战Vol.3 B. DP搬运工2

    水题大战Vol.3 B. DP搬运工2

    题目描述

    给你(n,K),求有多少个(1)(n) 的排列,恰好有(K)个数(i) 满足(a_{i-1},a_{i+1}) 都小于(a_i)

    输入格式

    一行两个整数(n,K)

    输出格式

    一行一个整数(ans)表示答案(mod 998244353)

    样例

    样例输入1

    4 1

    样例输出1

    16

    样例输入2

    10 3

    样例输出2

    1841152

    数据范围与提示

    对于 (25\%) 的测试点,(1 leq n,K leq 10)

    对于 (50\%) 的测试点,(1 leq n,K leq 100)

    对于 (100\%) 的测试点,(1 leq n,K leq 2000)

    保证数据有梯度

    分析

    一道典型的计数(DP)

    我们设 (f[i][j]) 为考虑完 (1 - i) ,有 (j) 个位置满足要求的方案数

    对于 (f[i-1][j]) 如果我们向序列中插入一个数 (i) 那么会有两种情况

    1、新插入的(i)插入到原来满足要求的(j)个位置旁边或者数列的两端,此时满足要求的位置仍然是(j)个,方案数为((j+1) imes 2)

    2、(i)插入到原数列的其它位置,此时满足要求的位置变为 (j+1) 个,方案数为 (i-(j+1) imes 2)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define mian main
    const int maxn=2e3+5;
    const int mod=998244353;
    int n,k,f[maxn][maxn];
    signed mian(){
    	scanf("%lld%lld",&n,&k);
    	f[1][0]=1,f[2][0]=2;
    	for(int i=3;i<=n;i++){
    		int m=min(k,i/2);
    		for(int j=0;j<=m;j++){
    			if(f[i-1][j]==0) continue;
    			int now=f[i-1][j];
    			int fa=(j+1)*2;
    			f[i][j]=(f[i][j]+f[i-1][j]*fa)%mod;
    			f[i][j+1]=(f[i][j+1]+f[i-1][j]*(i-fa))%mod;
    		}
    	}
    	printf("%lld
    ",f[n][k]);
    	return 0;
    }
    
    
  • 相关阅读:
    WPF-触发器
    WPF使用socket实现简单聊天软件
    git常用命令备忘
    (转载)WPF中的动画——(一)基本概念
    WPF中的依赖项属性
    C#中的索引器
    C#中的装箱拆箱
    编程语言的弱类型、强类型、动态类型、静态类型
    WPF中的数据驱动
    WPF中的命令简介
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13498358.html
Copyright © 2011-2022 走看看