[简单dp]toj1179
来源:互联网 发布:微博域名可以修改吗 编辑:程序博客网 时间:2024/06/05 01:59
题意给2n个点,问把他们两两连接有多少种方案,线段不允许交叉。
哎,感觉我好水。。。打了两天CF,但是笔记本掉帧太厉害,没兴致玩了。明天来鸡房呆着敲代码吧。。。
假设有p个点,当然题目给了n表达的是2n,所以p一定是偶数。顺序标号后发现,只需要考虑第一个点和谁连接就好了,因为有个线段不能相交的条件,所以一旦确定了第一个点连出的线段,这p个点就被这线段分成了两部分。很容易知道每部分的点数必须为偶数,否则一定产生交点。那么就很简单了,只需要考虑第一个点和第2,4,6,8,...,p连接的情况就可以了,定义dp[i]表示i个点的方案数,那么:
dp[i] = dp[i-2] + dp[2]*dp[i-4] + dp[4]*dp[i-6] + ... + dp[n-2]
为了表达方便,初始化dp[0]为1,那么上述转移就是:dp[i] = dp[j]*dp[i-2-j] (j=0,2,4,...,i-2)
C++代码:
#include<cstdio>typedef long long ll;const int MAX = 202;ll dp[MAX] = {1, 0, 1};int main() {for (int i = 4; i < MAX; i += 2) {for (int j = 2; j <= i; j += 2) {dp[i] += dp[i-j] * dp[j-2];}}int n;while (~scanf(" %d", &n) && (~n)) {printf("%lld\n", dp[n<<1]);}return 0;}当然,这是很糟糕的代码:点数达到一定量后溢出long long了,所以还是大整数(Java版):
import java.util.*;import java.math.*;public class Main {public static void main(String args[]) {BigInteger []dp = new BigInteger[202];dp[0] = BigInteger.valueOf(1);dp[2] = BigInteger.valueOf(1);for (int i = 4; i < 202; i += 2) {dp[i] = BigInteger.ZERO;for (int j = 2; j <= i; j += 2) {dp[i] = dp[i].add(dp[i-j].multiply(dp[j-2]));//System.out.println("dp[" + i + "] = " + dp[i]);}}Scanner cin = new Scanner(System.in);int n;while (cin.hasNextInt()) {n = cin.nextInt();if (n == -1) break;System.out.println(dp[n<<1]);}}}好吧,我狠无聊,好想打字...只是缓解一下两天没有敲代码的手瘾...吃翔去了╮(╯▽╰)╭
0 0
- [简单dp]toj1179
- 简单DP
- 简单dp
- 简单dp
- 简单DP
- 简单dp
- 简单DP
- 简单?dp
- 简单dp
- 简单dp
- 简单DP
- 简单DP
- 简单dp
- dp专题2--简单dp
- PKU3356 AGTC (简单DP)
- POJ2192 Zipper(简单DP)
- HDU 1087 简单DP
- zoj 2402 简单dp
- 黑马程序员_java基本语法
- UVA11732 Trie
- JQuery 实现checkbox与radio级联
- 分页的介绍-转
- 15道使用频率极高的基础算法题
- [简单dp]toj1179
- 学生管理系统开发代码分析笔记:jsp+java bean+servlet技术
- 扫盲贴---什么是封釉?车漆镀膜或者镀晶?
- Nodejs安装express提示不是内部或外部命令
- 黑马程序员 OC语言 - 3 面向对象(下)
- 黑马程序员_Java基础语法
- OpenBTS在GSM网络中设置
- Listview
- 程序员,周末是你充电的时候