当前位置: 首页 > news >正文

Codeforces Beta Round 14 (Div. 2) E. Camels (DP)

题目

Bob likes to draw camels: with a single hump, two humps, three humps, etc. He draws a camel by connecting points on a coordinate plane. Now he’s drawing camels with t humps, representing them as polylines in the plane. Each polyline consists of n vertices with coordinates (x1, y1), (x2, y2), …, (xn, yn). The first vertex has a coordinate x1 = 1, the second — x2 = 2, etc. Coordinates yi might be any, but should satisfy the following conditions:

  • there should be t humps precisely, i.e. such indexes j
    (2 ≤ j ≤ n - 1), so that yj - 1 < yj > yj + 1,
  • there should be precisely t - 1 such indexes j (2 ≤ j ≤ n - 1), so
    that yj - 1 > yj < yj + 1,
  • no segment of a polyline should be parallel to the Ox-axis,
  • all yi are integers between 1 and 4.

For a series of his drawings of camels with t humps Bob wants to buy a notebook, but he doesn’t know how many pages he will need. Output the amount of different polylines that can be drawn to represent camels with t humps for a given number n.

Input
The first line contains a pair of integers n and t (3 ≤ n ≤ 20, 1 ≤ t ≤ 10).

Output
Output the required amount of camels with t humps.

Examples

input

6 1

output

6

题解

这道题的状态表示很难想,反正我是看题解的

首先根据题目中给到的两个未知量 n, t,我们不难想到状态表示中一定是要包含 n 和 t,我们可以猜测状态方程为:

f[i][j] 表示前i个点中,包含j个驼峰的合法的方案数;

但是如何实现状态转移呢?

我们发现只用两维去表示状态无法写出转移方程,因为我们无法知道驼峰的高度,所谓的合法方案无法只被两维状态表示出来,那么我们就要引进新的状态:

用 a, b 表示上一个和上上个点的高度(y值)

因为只有知道了相邻的两个点的高度才能实现状态转移。

同时,我们不光要知道驼峰 j 的个数,还得知道驼谷 k 的个数,这样才能知道哪些方案是合法的,哪些不是。

所以最后的状态表示需要五维。

f[i][j][k][a][b] 表示填前i个y, j个波峰, k个波谷, 第i-1个y是a, 第i个y是b

知道了状态表示,状态转移就很容易写出了,直接写六重循环,分别枚举i,j,k,a,b,c(第i+1个点的y值),看满足驼峰还是满足驼谷,分别加一即可,如果状态不合法,直接延续之前的状态。

代码

#include<iostream>
#include<algorithm>
#include<cstring>using namespace std;typedef long long LL;const int N = 50;int n, t;
int f[22][22][22][5][5];int main()
{cin >> n >> t;for (int i = 1; i <= 4; i++)for (int j = 1; j <= 4; j++)if (i != j) f[2][0][0][i][j] = 1;for (int i = 2; i < n; i++)for (int j = 0; j <= t; j ++)for (int k = 0; k <= t - 1; k++)for (int a = 1; a <= 4; a++)for (int b = 1; b <= 4; b++){if(a != b)for (int c = 1; c <= 4; c++){if (b != c){if (a > b && b < c) f[i + 1][j][k + 1][b][c] += f[i][j][k][a][b]; // 这就是波谷else if (a < b && b > c) f[i + 1][j + 1][k][b][c] += f[i][j][k][a][b];else f[i + 1][j][k][b][c] += f[i][j][k][a][b];}}}LL ans = 0;for (int i = 1; i <= 4; i++)for (int j = 1; j <= 4; j++)ans += f[n][t][t - 1][i][j];cout << ans << endl;return 0;
}
http://www.lryc.cn/news/453656.html

相关文章:

  • CSID-GAN:基于生成对抗网络的定制风格室内平面设计框架论文阅读
  • 02SQLite
  • 学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
  • JDBC编程
  • Python : 类变量、静态方法、类方法
  • 大厂笔试现已经禁用本地IDE怎么看
  • 【PostgreSQL】入门篇——如何创建、删除和管理数据库及其用户,包括权限设置和角色管理
  • 网络安全:保护数字时代的堡垒
  • 【rCore OS 开源操作系统】Rust 字符串(可变字符串String与字符串切片str)
  • 远程过程调用RPC知识科普
  • Java - LeetCode面试经典150题 - 区间 (三)
  • NVIDIA网卡系列之ConnectX-6 DX规格信息(200G-PCIe 4.0x16-8PF1000VF-2019年发布)
  • 【案例】平面云
  • 测试用例的进阶二
  • zotero WebDAV同步忘记密码
  • 如何在 SQL 中创建一个新的数据库?
  • 《Linux从小白到高手》理论篇:Linux的进程管理详解
  • 【Qt】控件概述(3)—— 显示类控件
  • 数据库管理-第247期 23ai:全球分布式数据库-Schema对象(20241004)
  • Docker搭建一款开源的文档管理系统
  • 软件验证与确认实验一:静态分析
  • 基于SpringBoot+Vue的高校运动会管理系统
  • 什么东西可以当做GC Root,跨代引用如何处理?
  • Python深度学习:从神经网络到循环神经网络
  • C++输⼊输出
  • 卡码网KamaCoder 117. 软件构建
  • Acwing 线性DP
  • Docker面试-24年
  • ubuntu 安装k8s
  • No.4 笔记 | 探索网络安全:揭开Web世界的隐秘防线