DP搬运工1

题目描述

给你 \(n,K\) ,求有多少个 \(1\) 到 \(n\) 的排列,满足相邻两个数的 \(max\) 的和不超过 \(K\)。

输入格式

一行两个整数 \(n,K\)。

输出格式

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

样例

样例输入 1

4 10

样例输出 1

16

样例输入 2

10 66

样例输出 2

1983744

数据范围与提示

有 \(50\) 个测试点,第 \(i\) 个测试点为 \(n=i\),\(K \leqslant n^2\) 。

分析

用学长的题解来说这个叫做预设性 \(dp\) (其实也不知道啥意思)。意思大概就是枚举的是当前放哪个数(因为这几个题貌似都是这样)。

这个题我们考虑往里边插入数,因为每一次要取 \(max\) ,所以我们根据当前插入的值两边还可不可以放数来进行转移。

如果可以放入一个数,那么当前这个数之对和贡献一次。

如果两边可以放入两个数,那么这个数是没有贡献的。

如果两边都不放数,那么它贡献两次。

所以我们定义 \(f[i][j][k]\) 为放到第 \(i\) 个数,可以放的位置有 \(j\) 个。和为 \(k\)。

因为可以放在序列中,也可以放在两端,所以我们分开来考虑。

放在两端的时候就没有两边放两个数的情况了,但是两端有两种情况,所以加的时侯 \(f[i-1][j][k]\) 需要乘以 \(2\) 。

放在中间就需要考虑了,但是只有在当前数两边放一个的时候才用乘以 \(2\) ,所以我们就可以愉快的转移了。

代码

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
//以下好多行是卡常
const int L=1<<20;
char buffer[L],*S,*T;
#define lowbit(x) (x & -x)
#define getchar() (S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T)?EOF:*S++)
#define inline __inline__ __attribute__((__always_inline__))
#define max(a,b) (a>b?a:b)
#define re register
const int maxn = 52;
const int mod = 998244353;
int f[maxn][maxn][maxn*maxn];
int n;
inline int read(){
int s = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)){
if(ch == '-')f = -1;
ch = getchar();
}
while(isdigit(ch)){
s = s * 10 + ch - '0';
ch = getchar();
}
return s * f;
}
int main(){
n = read();
int K = read();
f[1][0][0] = 1;
for(int i = 2;i <= n;++i){
int jl1 = min(i,n-i)+1; //找到当前最多有多少位置能放
int jl2 = min(K,i*i);//找到当前最大的和
for(int j = 0;j <= jl1; ++j){
for(int k = 0;k <= jl2; ++k){
if(!f[i-1][j][k])continue;
int jl = f[i-1][j][k] * 2 % mod;//第一种放在两端的情况
f[i][j+1][k] = (f[i][j+1][k] + jl) % mod;
f[i][j][k+i] = (f[i][j][k+i] + jl) % mod;
if(!j)continue;
jl = f[i-1][j][k] * 1ll * j % mod;//以下是放在序列中间的情况
f[i][j+1][k] = (f[i][j+1][k] + jl) % mod;
f[i][j][k+i] = (f[i][j][k+i] + jl * 2ll % mod) % mod;
f[i][j-1][k+2*i] = (f[i][j-1][k+2*i] + jl) % mod;
}
}
}
int ans = 0;
for(int i = 0;i <= K;++i){//把小于等于 K 的所有情况都加起来
ans = (ans + f[n][0][i]) % mod;
}
printf("%d\n",ans);
}

DP搬运工1 [来自yyy--mengbier的预设型dp]的更多相关文章

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

    水题大战Vol.3 B. DP搬运工2 题目描述 给你\(n,K\),求有多少个\(1\)到\(n\) 的排列,恰好有\(K\)个数\(i\) 满足\(a_{i-1},a_{i+1}\) 都小于\(a ...

  2. 非确定性有穷状态决策自动机练习题Vol.3 D. Dp搬运工3

    非确定性有穷状态决策自动机练习题Vol.3 D. Dp搬运工3 题目描述 给定两个长度为 \(n\) 的排列,定义 \(magic(A,B)=∑_{i=1}^nmax(Ai,Bi)\) . 现在给定 ...

  3. 【题解】Luogu p2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat 树型dp

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  4. 区间型DP

    区间型DP是一类经典的动态规划问题,主要特征是可以先将大区间拆分成小区间求解最后由小区间的解得到大区间的解. 有三道例题 一.石子合并 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆. ...

  5. POJ3659 Cell Phone Network(树上最小支配集:树型DP)

    题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...

  6. POJ_1088 滑雪(记忆型DP+DFS)

    Description Michael喜欢滑雪,这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  7. UVA12186--树型DP

    树型DP第一题...就是从boss到底层员工是一个树型结构,底层员工想加薪,如果每个boss都有超过T%的员工要求加薪,他就会往更高的bOSs传达,问如果让根节点的大boss接到加薪要求,最少要有多少 ...

  8. POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断

    好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...

  9. 【XSY1905】【XSY2761】新访问计划 二分 树型DP

    题目描述 给你一棵树,你要从\(1\)号点出发,经过这棵树的每条边至少一次,最后回到\(1\)号点,经过一条边要花费\(w_i\)的时间. 你还可以乘车,从一个点取另一个点,需要花费\(c\)的时间. ...

随机推荐

  1. vue学习(一)初步了解 vue实例

    //html:<div id="app"> <p>{{msg}}<p></div> //script 需要引入jar包vue-2.4 ...

  2. HTML5其他标签应用

    HTML5 是下一代 HTML 标准. HTML5 多媒体 音频标签 <audio src=" "></audio> 视频标签 <video src= ...

  3. 编写优美Android注释的常用语法

    编写优美Android注释的常用语法   短期目标是定期能出一篇简文,希望自己能坚持下去~~~~( ̄_, ̄ )   附上Android君 今天要分享的是关于Android注释系统的一些强大功能!! 实 ...

  4. Django学习路25_ifequal 和 ifnotequal 判断数值是否相等及加减法 {{数值|add 数值}}

    {% ifequal 数值 数值 %} <body> {# 判断是否相等 #} num 当前的值 {{ num }}<br/> {% ifequal num 5 %} {# 判 ...

  5. PHP preg_quote() 函数

    preg_last_error 函数用于转义正则表达式字符.高佣联盟 www.cgewang.com 语法 string preg_quote ( string $str [, string $del ...

  6. Skill 返回一个数字list的大小排序信息

    https://www.cnblogs.com/yeungchie/ code procedure(ycSortList(numlist) prog((size sort) foreach(main ...

  7. BZOJ3772精神污染&BZOJ3488&luogu3242接水果

    LINK1:精神污染 LINK2:[ONTAK2010Highways](http://www.lydsy.com/JudgeOnline/problem.php?id=3488) LINK3:[接水 ...

  8. 【HNOI2011】数学作业 题解(递推+矩阵快速幂)

    题目链接 题目大意:求$1-n$所拼接起来的数$mod\ m$的值. ----------------------------------- 递推式子很好想:$f_i=f_{i-1}*10^{\lg ...

  9. 2017面向对象程序设计(Java)第十三周助教工作总结

    时间飞逝,本学期即将接近尾声.不知不觉同学们已经学习java十三个星期了,想必同学们对Java课程体系及内容有了更加深入的理解,也应该摸索出了一套适用于自己的学习方法. 下面我对上周工作做以简单总结: ...

  10. android基本操作

    1.页面跳转 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <androi ...