题目链接

题意:

  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个中选择在原来位置的物品进行交换,即

  1. #include <bits/stdc++.h>
  2.  
  3. const int MAXN = 2000 + 5;
  4. struct bign {
  5. int len, num[MAXN];
  6.  
  7. bign () {
  8. len = 0;
  9. memset(num, 0, sizeof(num));
  10. }
  11. bign (int number) {*this = number;}
  12. bign (const char* number) {*this = number;}
  13.  
  14. void DelZero ();
  15. void Put ();
  16.  
  17. void operator = (int number);
  18. void operator = (char* number);
  19.  
  20. bool operator < (const bign& b) const;
  21. bool operator > (const bign& b) const { return b < *this; }
  22. bool operator <= (const bign& b) const { return !(b < *this); }
  23. bool operator >= (const bign& b) const { return !(*this < b); }
  24. bool operator != (const bign& b) const { return b < *this || *this < b;}
  25. bool operator == (const bign& b) const { return !(b != *this); }
  26.  
  27. void operator ++ ();
  28. void operator -- ();
  29. bign operator + (const int& b);
  30. bign operator + (const bign& b);
  31. bign operator - (const int& b);
  32. bign operator - (const bign& b);
  33. bign operator * (const int& b);
  34. bign operator * (const bign& b);
  35. bign operator / (const int& b);
  36. //bign operator / (const bign& b);
  37. int operator % (const int& b);
  38. };
  39.  
  40. bign dp[805];
  41.  
  42. int main() {
  43. dp[0] = 0; dp[1] = 0; dp[2] = 1;
  44. for (int i=3; i<=800; ++i) {
  45. dp[i] = (dp[i-1] + dp[i-2]) * (i - 1);
  46. }
  47. int n;
  48. while (scanf ("%d", &n) == 1 && n != -1) {
  49. dp[n].Put ();
  50. puts ("");
  51. }
  52. return 0;
  53. }
  54.  
  55. void bign::DelZero () {
  56. while (len && num[len-1] == 0)
  57. len--;
  58.  
  59. if (len == 0) {
  60. num[len++] = 0;
  61. }
  62. }
  63.  
  64. void bign::Put () {
  65. for (int i = len-1; i >= 0; i--)
  66. printf("%d", num[i]);
  67. }
  68.  
  69. void bign::operator = (char* number) {
  70. len = strlen (number);
  71. for (int i = 0; i < len; i++)
  72. num[i] = number[len-i-1] - '0';
  73.  
  74. DelZero ();
  75. }
  76.  
  77. void bign::operator = (int number) {
  78.  
  79. len = 0;
  80. while (number) {
  81. num[len++] = number%10;
  82. number /= 10;
  83. }
  84.  
  85. DelZero ();
  86. }
  87.  
  88. bool bign::operator < (const bign& b) const {
  89. if (len != b.len)
  90. return len < b.len;
  91. for (int i = len-1; i >= 0; i--)
  92. if (num[i] != b.num[i])
  93. return num[i] < b.num[i];
  94. return false;
  95. }
  96.  
  97. void bign::operator ++ () {
  98. int s = 1;
  99.  
  100. for (int i = 0; i < len; i++) {
  101. s = s + num[i];
  102. num[i] = s % 10;
  103. s /= 10;
  104. if (!s) break;
  105. }
  106.  
  107. while (s) {
  108. num[len++] = s%10;
  109. s /= 10;
  110. }
  111. }
  112.  
  113. void bign::operator -- () {
  114. if (num[0] == 0 && len == 1) return;
  115.  
  116. int s = -1;
  117. for (int i = 0; i < len; i++) {
  118. s = s + num[i];
  119. num[i] = (s + 10) % 10;
  120. if (s >= 0) break;
  121. }
  122. DelZero ();
  123. }
  124.  
  125. bign bign::operator + (const int& b) {
  126. bign a = b;
  127. return *this + a;
  128. }
  129.  
  130. bign bign::operator + (const bign& b) {
  131. int bignSum = 0;
  132. bign ans;
  133.  
  134. for (int i = 0; i < len || i < b.len; i++) {
  135. if (i < len) bignSum += num[i];
  136. if (i < b.len) bignSum += b.num[i];
  137.  
  138. ans.num[ans.len++] = bignSum % 10;
  139. bignSum /= 10;
  140. }
  141.  
  142. while (bignSum) {
  143. ans.num[ans.len++] = bignSum % 10;
  144. bignSum /= 10;
  145. }
  146.  
  147. return ans;
  148. }
  149.  
  150. bign bign::operator - (const int& b) {
  151. bign a = b;
  152. return *this - a;
  153. }
  154.  
  155. bign bign::operator - (const bign& b) {
  156. int bignSub = 0;
  157. bign ans;
  158. for (int i = 0; i < len || i < b.len; i++) {
  159. bignSub += num[i];
  160. bignSub -= b.num[i];
  161. ans.num[ans.len++] = (bignSub + 10) % 10;
  162. if (bignSub < 0) bignSub = -1;
  163. }
  164. ans.DelZero ();
  165. return ans;
  166. }
  167.  
  168. bign bign::operator * (const int& b) {
  169. int bignSum = 0;
  170. bign ans;
  171.  
  172. ans.len = len;
  173. for (int i = 0; i < len; i++) {
  174. bignSum += num[i] * b;
  175. ans.num[i] = bignSum % 10;
  176. bignSum /= 10;
  177. }
  178.  
  179. while (bignSum) {
  180. ans.num[ans.len++] = bignSum % 10;
  181. bignSum /= 10;
  182. }
  183.  
  184. return ans;
  185. }
  186.  
  187. bign bign::operator * (const bign& b) {
  188. bign ans;
  189. ans.len = 0;
  190.  
  191. for (int i = 0; i < len; i++){
  192. int bignSum = 0;
  193.  
  194. for (int j = 0; j < b.len; j++){
  195. bignSum += num[i] * b.num[j] + ans.num[i+j];
  196. ans.num[i+j] = bignSum % 10;
  197. bignSum /= 10;
  198. }
  199. ans.len = i + b.len;
  200.  
  201. while (bignSum){
  202. ans.num[ans.len++] = bignSum % 10;
  203. bignSum /= 10;
  204. }
  205. }
  206. return ans;
  207. }
  208.  
  209. bign bign::operator / (const int& b) {
  210.  
  211. bign ans;
  212.  
  213. int s = 0;
  214. for (int i = len-1; i >= 0; i--) {
  215. s = s * 10 + num[i];
  216. ans.num[i] = s/b;
  217. s %= b;
  218. }
  219.  
  220. ans.len = len;
  221. ans.DelZero ();
  222. return ans;
  223. }
  224.  
  225. int bign::operator % (const int& b) {
  226.  
  227. bign ans;
  228.  
  229. int s = 0;
  230. for (int i = len-1; i >= 0; i--) {
  231. s = s * 10 + num[i];
  232. ans.num[i] = s/b;
  233. s %= b;
  234. }
  235.  
  236. return s;
  237. }

  

递推+高精度 UVA 10497 Sweet Child Makes Trouble(可爱的孩子惹麻烦)的更多相关文章

  1. 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 ...

  2. 递推+高精度+找规律 UVA 10254 The Priest Mathematician

    题目传送门 /* 题意:汉诺塔问题变形,多了第四个盘子可以放前k个塔,然后n-k个是经典的汉诺塔问题,问最少操作次数 递推+高精度+找规律:f[k]表示前k放在第四个盘子,g[n-k]表示经典三个盘子 ...

  3. PKU 2506 Tiling(递推+高精度||string应用)

    题目大意:原题链接有2×1和2×2两种规格的地板,现要拼2×n的形状,共有多少种情况,首先要做这道题目要先对递推有一定的了解.解题思路:1.假设我们已经铺好了2×(n-1)的情形,则要铺到2×n则只能 ...

  4. [luogu]P1066 2^k进制数[数学][递推][高精度]

    [luogu]P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻 ...

  5. [BZOJ1089][SCOI2003]严格n元树(递推+高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...

  6. 【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度

    1002: [FJOI2007]轮状病毒 Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同 ...

  7. BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

    题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring& ...

  8. 递推DP UVA 1366 Martian Mining

    题目传送门 /* 题意:抽象一点就是给两个矩阵,重叠的(就是两者选择其一),两种铺路:从右到左和从下到上,中途不能转弯, 到达边界后把沿途路上的权值相加求和使最大 DP:这是道递推题,首先我题目看了老 ...

  9. 递推 + 高精度 --- Tiling

    Tiling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7264   Accepted: 3528 Descriptio ...

随机推荐

  1. Redis 3.0 与 3.2 配置文件变化

    一.Redis3.0 与 3.2 配置文件对比 1. clone redis git clone https://github.com/antirez/redis.git 2. checkout分支 ...

  2. 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  3. SLF4J: Class path contains multiple SLF4J bindings.

    库冲突导致的异常,由于多次引入SLF4j包导致. It seems you have several implementation of SLF4J; you should exclude all t ...

  4. [原创]CSS3打造动态3D气球

    周末在江边晨跑的时候发现很多 当时心血来潮就想,应该可以在网页中实现一下 这几天得闲就做了一下,效果如下 (尽量在最新版本的chrome或者firefox中查看) demo下载在文章最后 预览 --& ...

  5. react+redux官方实例TODO从最简单的入门(1)-- 前言

    刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...

  6. (原创)微信支付SDK调用的核心代码与分析(基于Android)

    先上代码,后面会分析 String url = "http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=android"; ...

  7. ProgressBar---进度条

    最近在处理标题进度条时,耗费了一些时间,现在总结一下ProgressBar的相关知识,有不对的地方请大神们批评指正! 进度条主要有以下三种: 1.对话框进度条 2.标题进度条 注意:requestWi ...

  8. Java字节流和字符流区别

    1.字节流:直接操作文件本身. 2.字符流:通过缓冲区来操作文件. 所有的文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符是只有在内存中才会形成,所以在开发中,字节 ...

  9. 基于ACE的c++线程封装

    1. 基本需求 1) 一个基类,其某个方法代表一个线程的生命运行周期.之后通过继承自这个基类来实现个性化线程类: 2) 具备类似QObject的定时器设置功能: 3) 提供在线程对象中同步和异步执行方 ...

  10. Linux posix线程库总结

    由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...