递推+高精度 UVA 10497 Sweet Child Makes Trouble(可爱的孩子惹麻烦)
题意:
n个物品全部乱序排列(都不在原来的位置)的方案数。
思路:
dp[i]表示i个物品都乱序排序的方案数,所以状态转移方程。考虑i-1个物品乱序,放入第i个物品一定要和i-1个的其中一个交换位置,即
;考虑i-2个物品乱序,第i-1个和第i个首先在原来的位置,两种方法使得乱序,一种和第i个交换(不能和前i-2个交换,那样成dp[i-1]),还有一种是第i个先和第i-1个交换,再和前i-2个其中一个交换,即
,仔细想想,这个和dp[i-1]是不同的交换方法。
另外:
还有二维的dp写法,虽然高精度开不了,但是还是有启发意义。设dp[i][j]表示i个物品j个乱序的方案数,状态转移方程,最后一项的(i-j+1)的意思是从前i-1个中选择在原来位置的物品进行交换,即
。
- #include <bits/stdc++.h>
- const int MAXN = 2000 + 5;
- struct bign {
- int len, num[MAXN];
- bign () {
- len = 0;
- memset(num, 0, sizeof(num));
- }
- bign (int number) {*this = number;}
- bign (const char* number) {*this = number;}
- void DelZero ();
- void Put ();
- void operator = (int number);
- void operator = (char* number);
- bool operator < (const bign& b) const;
- bool operator > (const bign& b) const { return b < *this; }
- bool operator <= (const bign& b) const { return !(b < *this); }
- bool operator >= (const bign& b) const { return !(*this < b); }
- bool operator != (const bign& b) const { return b < *this || *this < b;}
- bool operator == (const bign& b) const { return !(b != *this); }
- void operator ++ ();
- void operator -- ();
- bign operator + (const int& b);
- bign operator + (const bign& b);
- bign operator - (const int& b);
- bign operator - (const bign& b);
- bign operator * (const int& b);
- bign operator * (const bign& b);
- bign operator / (const int& b);
- //bign operator / (const bign& b);
- int operator % (const int& b);
- };
- bign dp[805];
- int main() {
- dp[0] = 0; dp[1] = 0; dp[2] = 1;
- for (int i=3; i<=800; ++i) {
- dp[i] = (dp[i-1] + dp[i-2]) * (i - 1);
- }
- int n;
- while (scanf ("%d", &n) == 1 && n != -1) {
- dp[n].Put ();
- puts ("");
- }
- return 0;
- }
- void bign::DelZero () {
- while (len && num[len-1] == 0)
- len--;
- if (len == 0) {
- num[len++] = 0;
- }
- }
- void bign::Put () {
- for (int i = len-1; i >= 0; i--)
- printf("%d", num[i]);
- }
- void bign::operator = (char* number) {
- len = strlen (number);
- for (int i = 0; i < len; i++)
- num[i] = number[len-i-1] - '0';
- DelZero ();
- }
- void bign::operator = (int number) {
- len = 0;
- while (number) {
- num[len++] = number%10;
- number /= 10;
- }
- DelZero ();
- }
- bool bign::operator < (const bign& b) const {
- if (len != b.len)
- return len < b.len;
- for (int i = len-1; i >= 0; i--)
- if (num[i] != b.num[i])
- return num[i] < b.num[i];
- return false;
- }
- void bign::operator ++ () {
- int s = 1;
- for (int i = 0; i < len; i++) {
- s = s + num[i];
- num[i] = s % 10;
- s /= 10;
- if (!s) break;
- }
- while (s) {
- num[len++] = s%10;
- s /= 10;
- }
- }
- void bign::operator -- () {
- if (num[0] == 0 && len == 1) return;
- int s = -1;
- for (int i = 0; i < len; i++) {
- s = s + num[i];
- num[i] = (s + 10) % 10;
- if (s >= 0) break;
- }
- DelZero ();
- }
- bign bign::operator + (const int& b) {
- bign a = b;
- return *this + a;
- }
- bign bign::operator + (const bign& b) {
- int bignSum = 0;
- bign ans;
- for (int i = 0; i < len || i < b.len; i++) {
- if (i < len) bignSum += num[i];
- if (i < b.len) bignSum += b.num[i];
- ans.num[ans.len++] = bignSum % 10;
- bignSum /= 10;
- }
- while (bignSum) {
- ans.num[ans.len++] = bignSum % 10;
- bignSum /= 10;
- }
- return ans;
- }
- bign bign::operator - (const int& b) {
- bign a = b;
- return *this - a;
- }
- bign bign::operator - (const bign& b) {
- int bignSub = 0;
- bign ans;
- for (int i = 0; i < len || i < b.len; i++) {
- bignSub += num[i];
- bignSub -= b.num[i];
- ans.num[ans.len++] = (bignSub + 10) % 10;
- if (bignSub < 0) bignSub = -1;
- }
- ans.DelZero ();
- return ans;
- }
- bign bign::operator * (const int& b) {
- int bignSum = 0;
- bign ans;
- ans.len = len;
- for (int i = 0; i < len; i++) {
- bignSum += num[i] * b;
- ans.num[i] = bignSum % 10;
- bignSum /= 10;
- }
- while (bignSum) {
- ans.num[ans.len++] = bignSum % 10;
- bignSum /= 10;
- }
- return ans;
- }
- bign bign::operator * (const bign& b) {
- bign ans;
- ans.len = 0;
- for (int i = 0; i < len; i++){
- int bignSum = 0;
- for (int j = 0; j < b.len; j++){
- bignSum += num[i] * b.num[j] + ans.num[i+j];
- ans.num[i+j] = bignSum % 10;
- bignSum /= 10;
- }
- ans.len = i + b.len;
- while (bignSum){
- ans.num[ans.len++] = bignSum % 10;
- bignSum /= 10;
- }
- }
- return ans;
- }
- bign bign::operator / (const int& b) {
- bign ans;
- int s = 0;
- for (int i = len-1; i >= 0; i--) {
- s = s * 10 + num[i];
- ans.num[i] = s/b;
- s %= b;
- }
- ans.len = len;
- ans.DelZero ();
- return ans;
- }
- int bign::operator % (const int& b) {
- bign ans;
- int s = 0;
- for (int i = len-1; i >= 0; i--) {
- s = s * 10 + num[i];
- ans.num[i] = s/b;
- s %= b;
- }
- return s;
- }
递推+高精度 UVA 10497 Sweet Child Makes Trouble(可爱的孩子惹麻烦)的更多相关文章
- UVA 10497 - Sweet Child Makes Trouble 高精度DP
Children are always sweet but they can sometimes make you feel bitter. In this problem, you will see ...
- 递推+高精度+找规律 UVA 10254 The Priest Mathematician
题目传送门 /* 题意:汉诺塔问题变形,多了第四个盘子可以放前k个塔,然后n-k个是经典的汉诺塔问题,问最少操作次数 递推+高精度+找规律:f[k]表示前k放在第四个盘子,g[n-k]表示经典三个盘子 ...
- PKU 2506 Tiling(递推+高精度||string应用)
题目大意:原题链接有2×1和2×2两种规格的地板,现要拼2×n的形状,共有多少种情况,首先要做这道题目要先对递推有一定的了解.解题思路:1.假设我们已经铺好了2×(n-1)的情形,则要铺到2×n则只能 ...
- [luogu]P1066 2^k进制数[数学][递推][高精度]
[luogu]P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻 ...
- [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...
- 【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
1002: [FJOI2007]轮状病毒 Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同 ...
- BZOJ 1002 FJOI2007 轮状病毒 递推+高精度
题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring& ...
- 递推DP UVA 1366 Martian Mining
题目传送门 /* 题意:抽象一点就是给两个矩阵,重叠的(就是两者选择其一),两种铺路:从右到左和从下到上,中途不能转弯, 到达边界后把沿途路上的权值相加求和使最大 DP:这是道递推题,首先我题目看了老 ...
- 递推 + 高精度 --- Tiling
Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7264 Accepted: 3528 Descriptio ...
随机推荐
- Redis 3.0 与 3.2 配置文件变化
一.Redis3.0 与 3.2 配置文件对比 1. clone redis git clone https://github.com/antirez/redis.git 2. checkout分支 ...
- 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- SLF4J: Class path contains multiple SLF4J bindings.
库冲突导致的异常,由于多次引入SLF4j包导致. It seems you have several implementation of SLF4J; you should exclude all t ...
- [原创]CSS3打造动态3D气球
周末在江边晨跑的时候发现很多 当时心血来潮就想,应该可以在网页中实现一下 这几天得闲就做了一下,效果如下 (尽量在最新版本的chrome或者firefox中查看) demo下载在文章最后 预览 --& ...
- react+redux官方实例TODO从最简单的入门(1)-- 前言
刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...
- (原创)微信支付SDK调用的核心代码与分析(基于Android)
先上代码,后面会分析 String url = "http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=android"; ...
- ProgressBar---进度条
最近在处理标题进度条时,耗费了一些时间,现在总结一下ProgressBar的相关知识,有不对的地方请大神们批评指正! 进度条主要有以下三种: 1.对话框进度条 2.标题进度条 注意:requestWi ...
- Java字节流和字符流区别
1.字节流:直接操作文件本身. 2.字符流:通过缓冲区来操作文件. 所有的文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符是只有在内存中才会形成,所以在开发中,字节 ...
- 基于ACE的c++线程封装
1. 基本需求 1) 一个基类,其某个方法代表一个线程的生命运行周期.之后通过继承自这个基类来实现个性化线程类: 2) 具备类似QObject的定时器设置功能: 3) 提供在线程对象中同步和异步执行方 ...
- Linux posix线程库总结
由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...