博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LA 4123 (计数 递推) Glenbow Museum
阅读量:4595 次
发布时间:2019-06-09

本文共 1403 字,大约阅读时间需要 4 分钟。

题意:

这种所有边都是垂直或水平的多边形,可以用一个字符串来表示,一个270°的内角记作O,一个90°的内角记作R。

如果多边形内存在一个点,能看到该多边形所有的点,则这个多边形对应的序列是合法的。这里长度不作限制,只要长度适当能满足要求即可。

现给出序列长度,问有多少种序列符合要求。

分析:

书上分析地很清楚,罗列一下要点:

首先对于一个长度为n的合法序列,R的个数为(n+4)/2,O的个数为(n-4)/2,即R比O多4个

我们要找的序列满足要求:R比O多4个,没有两个O相邻。

这里先设计了一个O(n2)递推的状态,很好理解,看下面那个O(n)的递推

f(i, j, k)表示有i个R,有j对相邻的R,k(k=0表示R,k=1表示O)开头,R结尾的序列个数。

边界:

f(1, 0, 0) = 1,对应串R;f(1, 0, 1) = 1,对应串OR

状态转移方程:

f(i, j, k) = f(i-1, j, k) + f(i-1, j-1, k),第一个代表在最后面加OR,第二个表示在最后面加R

答案:

f((n+4)/2, 3, 0) + f((n+4)/2, 4, 1) + f((n+4)/2, 4, 0)

第一个表示开头结尾都是R的串,串中有3对相邻的R,因为串是环状的,所以首尾也算一对,共4对R

第二个是O开头,R结尾的串

第三个看起来是R开头结尾,而且中间还有4对R,但只要在最后加上一个O就行了,这样不影响R的个数,对数,总之不影响整个状态的表示。

1 #include 
2 3 const int maxn = 1000; 4 5 long long d[maxn + 10][5][2], ans[maxn + 10]; 6 7 void Init() 8 { 9 d[1][0][1] = d[1][0][0] = 1;10 for(int i = 2; i <= maxn; i++)11 for(int j = 0; j < 5; j++)12 for(int k = 0; k < 2; k++)13 {14 d[i][j][k] = d[i-1][j][k];15 if(j) d[i][j][k] += d[i-1][j-1][k];16 }17 18 for(int i = 4; i <= maxn; i+= 2)19 {20 int R = (i>>1) + 2;21 ans[i] = d[R][3][0] + d[R][4][1] + d[R][4][0];22 }23 }24 25 int main()26 {27 Init();28 int n, kase = 1;29 while(scanf("%d", &n) == 1 && n) printf("Case %d: %lld\n", kase++, ans[n]);30 }
代码君

 

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4319369.html

你可能感兴趣的文章
JavaScript系列教程(七):函数
查看>>
江中微型统计分析软件V1.0版本完成
查看>>
彻底搞懂CNN中的卷积和反卷积
查看>>
iOS中画各种图形
查看>>
javascript中的面向对象
查看>>
VirtualBox 下 CentOS6.5 网络配置(NAT) (公司内部用)
查看>>
面向对象三大基本特性,五大基本原则
查看>>
User32.dll 函数的相关方法整理
查看>>
Bootstarp 水平垂直居中
查看>>
LInux Centos7 重装yum
查看>>
HDU 3802Ipad,IPhone
查看>>
高德坐标转百度坐标并导航
查看>>
mpvue配合less
查看>>
查询一个表的不同数据,显示到一个表
查看>>
Unity随手记
查看>>
Swagger入门教程
查看>>
nginx日志定时切割脚本
查看>>
HashSet的实现原理
查看>>
oracle创建简单的包
查看>>
[POJ2689]Prime Distance
查看>>