博客
关于我
算法擂台微积分习题问题解答
阅读量:142 次
发布时间:2019-02-27

本文共 3887 字,大约阅读时间需要 12 分钟。

 
微积分习题
小王是大一的学生,想在寒假里强化一下微积分课程的学习,他从图书馆借了一套吉米多维奇的数学分析习题集。他决定在以后的
n
天里要做完上面的
S
道积分题。
为了能够尽快地完成任务,小王强迫自己第
i
天至少要做
ai
道积分题。但是,小王在假期里还有其他事情(例如过春节),每天的题量不能太多,他估计了一下,第
i
天做的积分题不能超过
bi
bi
ai
)道。
现在小王想知道,究竟能有多少种方案能够在
n
天里做完这
S
道习题呢?小王请你写个程序帮他算一算。
具体来说,一个方案就是每天做的微积分题的数目的序列,假设第
i
天完成
xi
道题(
xi
当然满足
ai
xi bi
,且
x
1
+x2+……+xn=S
)。那么向量
(x1, x2, …, xn)
就对应了一个方案。两个方案不同是指它们对应的向量不同。
【输入】
一共
n
+1
行,第一行是两个整数
n
S
,用空格分开,分别表示天数和题目数(
1 ≤ n ≤ 20
1 ≤ S ≤ 1000
);接下来
n
行每行两个整数,之间用空格隔开,分别表示第
i
天对做题数量的限制
ai
bi
0 ≤ ai bi S
)。
【输出】
一个整数,表示满足条件的方案数
T
【输入输出】
 
样例
A
样例
B
样例
C
样例
D
输入样例
3 11
2 5
1 6
3 4
8 20
1 4
2 8
1 5
2 7
4 7
2 5
2 8
1 3
10 55
0 1
0 2
0 3
0 4
0 5
0 8
0 8
0 8
0 9
0 10
15 123
1 100
2 100
3 100
4 100
5 100
6 100
7 100
8 100
9 100
10 100
11 100
12 100
13 100
14 100
15 100
输出样例
8
731
209
680
 
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
class BigNum
{
 vector<int> val;
public:
 static const int NUM = 10000;
 static const int WIDTH = 4;
 BigNum(int n = 0);
 friend ostream& operator << (ostream &out, const BigNum &n);
 bool operator != (const BigNum &n) const {return val != n.val;}
 BigNum& operator += (const BigNum &n2);
};
BigNum::BigNum(int n /* = 0 */)
{
 do // 保证val至少有一个元素
 {
  int a = n / NUM;
  int b = n % NUM;
  val.push_back(b);
  n = a;
 } while(n > 0);
}
BigNum& BigNum::operator += (const BigNum &n2)
{
 if (val.size() < n2.val.size()) // n2短
  val.resize(n2.val.size());
 transform(n2.val.begin(), n2.val.end(), val.begin(), val.begin(), plus<int>());
 int lastAdd = 0;
 for (vector<int>::iterator it = val.begin(); it != val.end(); ++it)
 {
  *it += lastAdd;
  if (*it >= BigNum::NUM)
  {
   *it -= BigNum::NUM;
   lastAdd = 1;
  }
  else
   lastAdd = 0;
 }
 if (lastAdd == 1)
  val.push_back(1);
 return *this;
}
ostream& operator << (ostream &out, const BigNum &n)
{
 if (n.val.size() == 1)  // 只有一个数
  return out << n.val[0];
 out << n.val.back();
 char c = out.fill('0');
 for (vector<int>::const_reverse_iterator it = n.val.rbegin()+1;
  it != n.val.rend(); ++it)
  out << setw(BigNum::WIDTH) << *it;
 return out << setfill(c);
}
#if 1 // 记录表法
const int MAX_N = 20;
const int MAX_S = 1000;
int n, S;
int a[MAX_N], b[MAX_N];
BigNum T[MAX_N][MAX_S + 1] = {
{0}}; // 记录表
BigNum Cal(int day, int done, int min, int max)
{
 int left = S - done;   // 还有多少题要做
 if (left < min || left > max) // 超出可能的做题范围
  return 0;     // 方案必不成功,部分方案数为0
 if (day == n - 1)    // 最后一天,方案必然可能
  return 1;     // 部分方案数为1,递归终止
 if (T[day][done] != 0)   // 已经计算过
  return T[day][done];
 BigNum total = 0;    // 部分方案数
 for (int t = a[day]; t <= b[day]; t++)   // 枚举
  total += Cal(day + 1, done + t, min-a[day], max-b[day]); // 递归计算
 T[day][done] = total;   // 记录下来
 return total;
}
int main()
{
 // 读入数据
 cin >> n >> S;
 for (int i = 0; i < n; i++)
  cin >> a[i] >> b[i];
 int min = 0, max = 0;  // 最少和最多做题数量
 for (int i = 0; i < n; i++)
 {
  min += a[i];
  max += b[i];
 }
 cout << Cal(0, 0, min, max) << endl;
 return 0;
}
#else // 动态规划算法
const int MAX_N = 20;
const int MAX_S = 1000;
int n, S;
int a[MAX_N], b[MAX_N];
BigNum fa[MAX_N][MAX_S+1];
int main()
{
 // 读入数据
 cin >> n >> S;
 for (int i = 0; i < n; i++)
  cin >> a[i] >> b[i];
 int leftMin = 0, leftMax = 0; // 还剩下的天中最少和最多做题数
 for (int i = 0; i < n; i++)
 {
  leftMin += a[i];
  leftMax += b[i];
 }
 // 第0天
 int realMin = a[0], realMax = b[0]; // 到当前天为止,最少和最多做题数
 leftMin -= a[0]; leftMax -= b[0];
 if (realMin < S - leftMax) realMin = S - leftMax;
 if (realMax > S - leftMin) realMax = S - leftMin;
 for (int t = realMin; t <= realMax; t++)
  fa[0][t] = 1;
 for (int day = 1; day < n; day++)
 {
  realMin += a[day]; realMax += b[day];
  leftMin -= a[day]; leftMax -= b[day];
  if (realMin < S - leftMax) realMin = S - leftMax;
  if (realMax > S - leftMin) realMax = S - leftMin;
  for (int tall = realMin; tall <= realMax; tall++) // 对于总题量
   for (int t = a[day]; t <= b[day] && t <= tall; t++)
    fa[day][tall] += fa[day-1][tall-t]; // 累计之前的可能方案数
 }
 cout << fa[n-1][S] << endl;
 return 0;
}
#endif
 

转载地址:http://vdgf.baihongyu.com/

你可能感兴趣的文章
NIFI从MySql中离线读取数据再导入到MySql中_不带分页处理_01_QueryDatabaseTable获取数据_原0036---大数据之Nifi工作笔记0064
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_无分页功能_02_转换数据_分割数据_提取JSON数据_替换拼接SQL_添加分页---大数据之Nifi工作笔记0037
查看>>
NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
查看>>
nifi使用过程-常见问题-以及入门总结---大数据之Nifi工作笔记0012
查看>>
NIFI分页获取Mysql数据_导入到Hbase中_并可通过phoenix客户端查询_含金量很高的一篇_搞了好久_实际操作05---大数据之Nifi工作笔记0045
查看>>
NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049
查看>>
NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
查看>>
NIFI同步MySql数据源数据_到原始库hbase_同时对数据进行实时分析处理_同步到清洗库_实际操作06---大数据之Nifi工作笔记0046
查看>>
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>
NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
查看>>
NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_处理器介绍_处理过程说明---大数据之Nifi工作笔记0019
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>