BOI 2003 Problem. Spaceship
题目
The Romanian Space Association (RSA) discovered a new asteroid, which they called BOI2003. RSA is eager to
explore the asteroid BOI2003, so they built a spaceship to carry scientists to the asteroid. The spaceship they built
has some peculiar features. When the spaceship leaves Earth for the first time it should carry exactly S scientists.
When the spaceship arrives at the asteroid BOI2003, a single scientist lands and the spaceship returns to take over
other S scientists.
The first scientist that landed on BOI2003 suspects the existence of a dangerous virus on the asteroid. Thus he
suggests that, until the research is over, not a single scientist that traveled to BOI2003 should leave the spaceship
when it arrives to Earth.
To be more specific, let’s assume that the scientists are denoted by integers starting at 1. The spaceship works in
the following way:
– the first time it leaves Earth, the spaceship carries the scientists 1, 2, ..., S; one of these scientists lands on the
asteroid and the other S-1 scientists return to Earth (but do not get off the ship);
– the second time the spaceship leaves Earth, the scientists S+1, S+2, ..., 2S gather the S-1 scientists that came
back, and the spaceship carries these 2S-1 scientists to BOI2003; one of them lands on the asteroid and the
spaceship returns to Earth with 2S-2 scientists (again, they do not get off the ship);
– the third time, the scientists 2S+1, 2S+2, ..., 3S together with the other 2S-2 scientists who already are on
the spaceship, travel to BOI2003 and one of them lands on the asteroid;
– and so on.
After N rides, a research team consisting of N scientists has been carried over and is working on the asteroid
BOI2003.
Task
Write a program that determines the number of possibilities to form the research team.
Input data (file: ship.in)
The single line of the input file contains the integers S and N, separated by a single space.
Output data (file: ship.out)
The single line of the output file contains an integer K, representing the number of possibilities to form the
research team.
Constraints
1 ≤ S ≤ 10
1 ≤ N ≤ 40
The spaceship has unlimited capacity.
The order in which the members of the team arrive on the asteroid does not matter.
Example
ship.in ship.out
2 3 14
Time limit: 0.4 seconds/test.
分析
看完题目其实就会有一个第一感觉,这道题的本质是一道数学题。这时候就要掏出纸和笔打草稿做计算。翻译过来,这道题就是:有一些人,先从前s个人里选一个,再从前2s个人里选一个……求这样选的方法数。
这题的精髓在于首先要找到这道题目与组合之间的关系。然后再发现这些数字组成的序列其实是一个杨辉三角。
在我的程序当中,我用一个init函数来计算C数组当中存储的数字(杨辉三角第s行),C[i]对应的是Cis。
init函数的写法是有点技巧的。因为对于计算一个C[j]需要用到的两个数字是上一行的C[j]和C[j-1],而如果从左往右计算,就会发现需要用的数字已经被更新过了。所以要做的是从右往左算。这样可以让本来需要开一个二维数组或者要写几行代码的函数变得非常简洁明了。
接下来有一个f数组,f[i][j]表示i个s人小组里选出j个人的可能情况数量。想到就是C[k]*f[i-1][j-k]的和。也就是i-1个小组选j-k个人的情况数。
(千万别忘了初始化数组233,调了好久)
程序
(第一个程序有高精度算法,添加了运算符重载。当然如果你只想了解核心算法,只要看第二段程序就可以了。两段程序在本质上是相同的。)
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAX = 100; 4 struct BIG 5 { 6 int len, s[MAX]; 7 BIG() 8 { 9 memset(s, 0, sizeof(s)); 10 len = 1; 11 } 12 BIG(int num) 13 { 14 *this = num; 15 } 16 BIG(const char* num) 17 { 18 *this = num; 19 } 20 BIG operator = (int num) 21 { 22 char s[MAX]; 23 sprintf(s, "%d", num); 24 *this = s; 25 return *this; 26 } 27 string str() const 28 { 29 string res = ""; 30 for(int i = 0; i < len; i++) 31 res = (char)(s[i] + '0') + res; 32 if(res == "") res = "0"; 33 return res; 34 } 35 void clean() 36 { 37 while(len > 1 && !s[len-1]) 38 len--; 39 } 40 BIG operator = (const char* num) 41 { 42 len = strlen(num); 43 for(int i = 0; i < len; i++) 44 s[i] = num[len-i-1] - '0'; 45 return *this; 46 } 47 BIG operator + (const BIG& b) const 48 { 49 BIG c; 50 c.len = 0; 51 for(int i = 0, g = 0; g || i < max(len, b.len); i++) 52 { 53 int x = g; 54 if(i < len) x += s[i]; 55 if(i < b.len) x += b.s[i]; 56 c.s[c.len++] = x % 10; 57 g = x / 10; 58 } 59 return c; 60 } 61 BIG operator * (const BIG& b) 62 { 63 BIG c; c.len = len + b.len; 64 for(int i = 0; i < len; i++) 65 for(int j = 0; j < b.len; j++) 66 c.s[i+j] += s[i] * b.s[j]; 67 for(int i = 0; i < c.len-1; i++) 68 { 69 c.s[i+1] += c.s[i] / 10; 70 c.s[i] %= 10; 71 } 72 c.clean(); 73 return c; 74 } 75 BIG operator - (const BIG& b) { 76 BIG c; 77 c.len = 0; 78 for(int i = 0, g = 0; i < len; i++) 79 { 80 int x = s[i] - g; 81 if(i < b.len) 82 x -= b.s[i]; 83 if(x >= 0) 84 g = 0; 85 else 86 { 87 g = 1; 88 x += 10; 89 } 90 c.s[c.len++] = x; 91 } 92 c.clean(); 93 return c; 94 } 95 bool operator < (const BIG& b) const 96 { 97 if(len != b.len) 98 return len < b.len; 99 for(int i = len-1; i >= 0; i--) 100 if(s[i] != b.s[i]) 101 return s[i] < b.s[i]; 102 return false; 103 } 104 bool operator > (const BIG& b) const 105 { 106 return b < *this; 107 } 108 bool operator <= (const BIG& b) 109 { 110 return !(b > *this); 111 } 112 bool operator == (const BIG& b) 113 { 114 return !(b < *this) && !(*this < b); 115 } 116 BIG operator += (const BIG& b) 117 { 118 *this = *this + b; 119 return *this; 120 } 121 }; 122 ostream& operator << (ostream &out, const BIG& x) 123 { 124 out << x.str(); 125 return out; 126 } 127 long long s, p, n; 128 BIG f[60][60], C[20]; 129 void init(int n) 130 { 131 for (int i = 2; i <= n; i++) 132 for (int j = i; j >= 1; j--) 133 C[j] = C[j] + C[j-1]; 134 } 135 int main() 136 { 137 freopen("spaceship.in","r",stdin); 138 freopen("spaceship.out","w",stdout); 139 cin >> s >> n; 140 C[0] = 1, C[1] = 1; 141 142 //Initiate combination array 143 init(s); 144 f[0][0] = 1; 145 for (int i = 1; i <= n; i++) 146 { 147 for (int j = 0; j <= i; j++) 148 { 149 if (j < i) 150 p = 0; 151 else 152 p = 1; 153 for (int k = p; k <= j; k++) 154 f[i][j] += C[k]*f[i-1][j-k]; 155 } 156 } 157 cout << f[n][n] << endl; 158 return 0; 159 }
1 #include <bits/stdc++.h> 2 using namespace std; 3 long long C[11], s, f[41][41], p, n; 4 void init(int n) 5 { 6 for (int i = 2; i <= n; i++) 7 for (int j = i; j >= 1; j--) 8 C[j] = C[j] + C[j-1]; 9 } 10 int main() 11 { 12 freopen("spaceship.in","r",stdin); 13 freopen("spaceship.out","w",stdout); 14 cin >> s >> n; 15 C[0] = 1, C[1] = 1; 16 17 init(s); 18 f[0][0] = 1; 19 for (int i = 1; i <= n; i++) 20 { 21 for (int j = 0; j <= i; j++) 22 { 23 if (j < i) 24 p = 0; 25 else 26 p = 1; 27 for (int k = p; k <= j; k++) 28 f[i][j] += C[k]*f[i-1][j-k]; 29 } 30 } 31 cout << f[n][n] << endl; 32 return 0; 33 }
转载于:https://www.cnblogs.com/OIerPrime/p/8313087.html
BOI 2003 Problem. Spaceship相关推荐
- [BOI 2003]团伙
洛谷 P1892 注意题目里只叙述了两条规则: 我的朋友的朋友是我的朋友 我的敌人的敌人是我的朋友 而敌人的朋友.朋友的敌人如何并没有交待 记录结点 u 的朋友有哪些,敌人有哪些就好了 #includ ...
- 2003 Problem C 等腰梯形
问题 C: 等腰梯形 时间限制: 1 Sec 内存限制: 32 MB 题目描述 请输入高度h,输入一个高为h,上底边长为h 的等腰梯形(例如h=4,图形如下). **** ****** ****** ...
- HDU 2003 求绝对值
http://acm.hdu.edu.cn/showproblem.php?pid=2003 Problem Description 求实数的绝对值. Input 输入数据有多组,每组占一行,每行包含 ...
- Symbian错误查询
一般错误 KErrNone 0 KErrNotFound -1 不能找到指定对象 KErrGeneral -2 一般错误(不可预料) KEr ...
- B - Friends
Description Problem I Friends There is a town with N citizens. It is known that some pairs of people ...
- codeup墓地目录(算法笔记习题刷题笔记)
在线codeup contest 地址:http://codeup.cn/contest.php Contest100000575 - <算法笔记>3.1小节--入门模拟->简单模拟 ...
- php打印n乘n沙漏形状图形,《算法笔记》3.3小节——入门模拟-图形输出
@[TOC] Contest100000577 - <算法笔记>3.3小节--入门模拟->图形输出 1933 Problem A 输出梯形 #include #include #in ...
- codeup墓地目录
代码内容为原创C++ 在线codeup contest 地址:http://codeup.cn/contest.php Contest100000575 - <算法笔记>3.1小节--入门 ...
- Avril Lavigne
Avril Lavigne -- 艾薇儿 一.基本资料 中文名( Name ):艾微儿 拉维妮 英文名: Avril R. Lavigne 家乡地:加拿大安大略省,纳帕尼镇 出生日( Birthday ...
最新文章
- svn错误 is already locked 解决方案
- 按键精灵文字识别插件_按键精灵——如何实现办公自由(二)
- 【遥感数字图像处理】实验:遥感图像显示与数据输入/输出(Erdas版)
- 自动检测技术学习心得体会_国培计划(2020)—学校管理团队信息化领导力提升培训心得体会...
- bootstrap 垂直居中 布局_CSS3 flex 布局必须要掌握的知识点
- Trident State译文
- 打开excel显示php拓展名,新建xls文件提示扩展名不一致
- 微信公布10月朋友圈十大谣言 包括牙膏能杀灭幽门螺杆菌等
- Android10一直获取IP地址,Android 获取IP地址的实现方法
- hpml350服务器安装系统,安装HP ML350
- 分治法--二分查找、乘方、斐波那契数
- python第四周作业_马哥2016全新Linux+Python高端运维班第四周作业
- python中颜色表_python 颜色表
- C语言-超市仓库管理系统的设计与实现
- PSQLException: An I/O error occurred问题排查
- 新南威尔士大学纯硅量子计算机,新南威尔士大学工程科学硕士-电气工程小方向课程解析...
- GP6创建tablespace 和GP4的差别
- Android9.0 完全隐藏导航栏、状态栏
- 安装Swoole报错 make: *** [php_swoole_cxx.lo] Error 1
- 微星B450M迫击炮MAX开启CPU虚拟化功能