题目

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相关推荐

  1. [BOI 2003]团伙

    洛谷 P1892 注意题目里只叙述了两条规则: 我的朋友的朋友是我的朋友 我的敌人的敌人是我的朋友 而敌人的朋友.朋友的敌人如何并没有交待 记录结点 u 的朋友有哪些,敌人有哪些就好了 #includ ...

  2. 2003 Problem C 等腰梯形

    问题 C: 等腰梯形 时间限制: 1 Sec  内存限制: 32 MB 题目描述 请输入高度h,输入一个高为h,上底边长为h 的等腰梯形(例如h=4,图形如下). **** ****** ****** ...

  3. HDU 2003 求绝对值

    http://acm.hdu.edu.cn/showproblem.php?pid=2003 Problem Description 求实数的绝对值. Input 输入数据有多组,每组占一行,每行包含 ...

  4. Symbian错误查询

    一般错误 KErrNone  0                       KErrNotFound  -1 不能找到指定对象      KErrGeneral  -2 一般错误(不可预料) KEr ...

  5. B - Friends

    Description Problem I Friends There is a town with N citizens. It is known that some pairs of people ...

  6. codeup墓地目录(算法笔记习题刷题笔记)

    在线codeup contest 地址:http://codeup.cn/contest.php Contest100000575 - <算法笔记>3.1小节--入门模拟->简单模拟 ...

  7. php打印n乘n沙漏形状图形,《算法笔记》3.3小节——入门模拟-图形输出

    @[TOC] Contest100000577 - <算法笔记>3.3小节--入门模拟->图形输出 1933 Problem A 输出梯形 #include #include #in ...

  8. codeup墓地目录

    代码内容为原创C++ 在线codeup contest 地址:http://codeup.cn/contest.php Contest100000575 - <算法笔记>3.1小节--入门 ...

  9. Avril Lavigne

    Avril Lavigne -- 艾薇儿 一.基本资料 中文名( Name ):艾微儿 拉维妮 英文名: Avril R. Lavigne 家乡地:加拿大安大略省,纳帕尼镇 出生日( Birthday ...

最新文章

  1. svn错误 is already locked 解决方案
  2. 按键精灵文字识别插件_按键精灵——如何实现办公自由(二)
  3. 【遥感数字图像处理】实验:遥感图像显示与数据输入/输出(Erdas版)
  4. 自动检测技术学习心得体会_国培计划(2020)—学校管理团队信息化领导力提升培训心得体会...
  5. bootstrap 垂直居中 布局_CSS3 flex 布局必须要掌握的知识点
  6. Trident State译文
  7. 打开excel显示php拓展名,新建xls文件提示扩展名不一致
  8. 微信公布10月朋友圈十大谣言 包括牙膏能杀灭幽门螺杆菌等
  9. Android10一直获取IP地址,Android 获取IP地址的实现方法
  10. hpml350服务器安装系统,安装HP ML350
  11. 分治法--二分查找、乘方、斐波那契数
  12. python第四周作业_马哥2016全新Linux+Python高端运维班第四周作业
  13. python中颜色表_python 颜色表
  14. C语言-超市仓库管理系统的设计与实现
  15. PSQLException: An I/O error occurred问题排查
  16. 新南威尔士大学纯硅量子计算机,新南威尔士大学工程科学硕士-电气工程小方向课程解析...
  17. GP6创建tablespace 和GP4的差别
  18. Android9.0 完全隐藏导航栏、状态栏
  19. 安装Swoole报错 make: *** [php_swoole_cxx.lo] Error 1
  20. 微星B450M迫击炮MAX开启CPU虚拟化功能

热门文章

  1. Java-Web机试练习题一、后台管理系统——管理员管理模块
  2. 野史杂谈,西游记令人崩溃的真相
  3. MyBatis的框架架构设计是怎么样的?
  4. alter system flush oracle的缓存
  5. 使用 case when进行行列转换
  6. servlet的理解
  7. Phoenix连接安全模式下的HBase集群
  8. TT 安装 之 AIX
  9. 简朴的生活、高贵的灵魂是人生的至高境界。——杨绛
  10. ZOJ3865:Superbot(BFS) The 15th Zhejiang University Programming Contest