NOIP模拟17.9.22

前进!
【问题描述】
数轴的原点上有一只青蛙。青蛙要跳到数轴上≥ 的位置去,但很不幸数轴
上有个区间是禁区,不能进入。青蛙会选择一个长度,从原点开始每次向右
跳长度为的一段。一路上青蛙会停的位置是0, , 2,…直到跳到了≥ 的位置,
任意一个位置都不能在禁区中。请求出的最小值,注意可以是实数。
【输入格式】
输入文件为susume.in。
输入文件的第一行包含两个整数和,含义如问题描述中所述。
接下来行,每行描述一个禁区。每行有两个整数和,代表数轴上(, )的
区间是禁区。保证有0 ≤ < ≤ 。
【输出格式】
输出文件为susume.out。
输出一行,代表的最小值。精度要求请参考评分方法。
【样例输入1】
2 25
11 21
3 7
【样例输出1】
10.5
【样例1 解释】
第一步跳到了 = 10.5,第二步跳到 = 21,第三步就跳到了≥ 的位置。
可以证明这个解是最小的解。
【样例输入2】
2 100
0 50
50 100
【样例输出2】
50.0

【题解】

考场上想出正解,但是因为SPJ所以没测

不难证明一定会在某次跳跃跳到某个区间的右端点

这样我们枚举是哪一个右端点,不断/2,/3,/4.../r作为

步长L。然后在On时间判断是否合法即可

挂标称了

 1 //#line 7 "TheFrog.cpp"
2 #include <cstdlib>
3 #include <cstring>
4 #include <cstdio>
5 #include <cmath>
6 #include <climits>
7 #include <algorithm>
8 #include <vector>
9 #include <string>
10 #include <iostream>
11 #include <map>
12 #include <queue>
13 #include <utility>
14 #include <ctime>
15 #include <sstream>
16 using namespace std;
17
18 typedef long long ll;
19 #define pair(x, y) make_pair(x, y)
20
21 #define N 50
22
23 class TheFrog {
24 public:
25 static const double eps = 1e-9;
26
27 pair<double, double> p[N + 1];
28 int n, D_;
29 double ans, m;
30
31 inline bool check(double x) {
32 for (int i = 1; i <= n; ++i) {
33 int ds = (int)(p[i].first / x + eps);
34 if (x * (double)(ds + 1) < p[i].second - eps)
35 return false;
36 }
37 return true;
38 }
39
40 double getMinimum(int D, vector <int> L, vector <int> R) {
41 ans = 1e10, m = 1e10, D_ = D;
42 n = L.size();
43 for (int i = 1; i <= n; ++i) p[i] = pair((double)L[i - 1], (double)R[i - 1]);
44 for (int i = 0; i < n; ++i) m = min(m, (double)R[i] - L[i]);
45 sort(p + 1, p + n + 1);
46 for (int i = 1; i <= n; ++i) {
47 double x = p[i].second;
48 int div = (int)(x / ans);
49 while (x / (double)div > m - eps) {
50 if (check(x / (double)div)) ans = min(ans, x / (double)div);
51 ++div;
52 }
53 }
54 return ans;
55 }
56 };
57
58 int n, D;
59 vector <int> L, R;
60
61 int main() {
62 freopen("susume.in", "r", stdin);
63 freopen("susume.out", "w", stdout);
64
65 TheFrog solution;
66 scanf("%d%d", &n, &D);
67 for (int i = 1; i <= n; ++i) {
68 int l, r;
69 scanf("%d%d", &l, &r);
70 L.push_back(l), R.push_back(r);
71 }
72
73 double ans = solution.getMinimum(D, L, R);
74 printf("%.10lf\n", ans);
75
76 fclose(stdin);
77 fclose(stdout);
78 return 0;
79 }

T1

统计
【问题描述】
给定长度为的序列。记 = {<, =,…, >},你需要计算下面的表达式的值:
max
C∈E
− min
I∈E

E⊆L
E MN
说得通俗一点,就是序列的元素构成了集合(序列中值相同的多个元素
在中也被视为不同的元素),求的所有大小为的子集中,元素的最大值减最
小值,之和。
由于答案可能很大,输出答案对取模之后得到的结果。
【输入格式】
输入数据的第一行包含三个整数、和。
接下来一行,包含个整数,代表序列。
【输出格式】
输出一行,包含一个整数,即为答案。
【样例】
setdiff.in setdiff.out
4 2 10007
10 20 30 40
100
【样例解释】
一共有6 个可选的子集:
• {10, 20},最大值为20,最小值为10;
• {10, 30},最大值为30,最小值为10;
• {10, 40},最大值为40,最小值为10;
• {20, 30},最大值为30,最小值为20;
• 20, 40 ,最大值为40,最小值为20;
• {30, 40},最大值为40,最小值为30。
【数据规模和约定】
对于30%的数据, ≤ 20。
对于60%的数据, ≤ 5000。
对于100%的数据,1 ≤ ≤ ≤ 100000,0 ≤ R ≤ 106,2 ≤ ≤ 106 + 7且
为质数。

【题解】

这个题的那个绝对值太迷惑了,去掉绝对值肯定知道

把式子化一下啊,真是蠢啊。。。。。。。。。

排个序,组合算一下就好了

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <cstring>
5 #include <algorithm>
6 #define max(a, b) ((a) > (b) ? (a) : (b))
7 #define min(a, b) ((a) < (b) ? (a) : (b))
8
9 inline void read(long long &x)
10 {
11 x = 0;char ch = getchar(), c = ch;
12 while(ch < '0' || ch > '9')c = ch, ch = getchar();
13 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
14 if(c == '-')x = -x;
15 }
16
17 const int INF = 0x3f3f3f3f;
18 const int MAXN = 100000 + 10;
19
20 long long n, k, p, num[MAXN], ans, f[MAXN];
21
22 long long pow(long long a, long long b)
23 {
24 long long r = 1, base = a % p;
25 for(;b;b >>= 1)
26 {
27 if(b & 1) r *= base, r %= p;
28 base *= base, base %= p;
29 }
30 return r;
31 }
32
33 inline long long ni(long long num)
34 {
35 return pow(num, p - 2);
36 }
37
38 long long C(long long n, long long m)
39 {
40 if(n < m)return 0;
41 return ((f[n] * ni(f[m]))%p * ni(f[n - m]))%p;
42 }
43
44 int main()
45 {
46 read(n), read(k), read(p);
47 f[0] = 1;
48 for(register int i = 1;i <= n;++ i)
49 f[i] = f[i - 1] * i, f[i] %= p;
50 for(register int i = 1;i <= n;++ i)
51 read(num[i]);
52 std::sort(num + 1, num + 1 + n);
53 for(register int i = k;i <= n;++ i)
54 ans += C(i - 1, k - 1) * (num[i] % p) % p;
55 std::sort(num + 1, num + 1 + n, std::greater<int>());
56 for(register int i = k;i <= n;++ i)
57 ans -= C(i - 1, k - 1) * (num[i] % p) % p, ans = (ans%p + p)%p;
58 printf("%d", ans);
59 return 0;
60 }

T2

旅行
【问题描述】
给定一个长度为的序列<, =,…, >。定义序列的代价为R − RU<
>5<
RM< 。
你现在可以任意次交换相邻的两个数,但是除了第一次交换以外,每次交换
的两个数的位置都应该在前一次交换的两个数的位置的右边。
比如说,第一次交换了(=, 7)这两个数,第二次就不能交换(<, =)或者
(=, 7),但是可以交换(7, V)或者(V, W)等。
求任意交换之后序列的最小代价。
【输入格式】
输入数据第一行一个整数。
接下来一行包含个整数,代表数列的每个元素。
【输出格式】
输出一行,代表最小代价。
【样例输入】
4
2 3 4 1
【样例输出】
4
【样例解释】
第一次,交换(<, =),数列变成{3,2,4,1}。
第二次,交换(=, 7),数列变成{3,4,2,1}。
可以证明这是最优方案。
【数据规模和约定】
对于10%的数据, ≤ 10。
对于20%的数据, ≤ 18。
对于50%的数据, ≤ 100。
对于100%的数据, ≤ 2000,R ≤ 100000。

【题解】

DP神题。

我们把i标位1意味着i与i + 1交换

i标位0意味着i与i + 1不交换

我们发现如果两个1之间夹着0,那么这两个1互不影响

如果是连续的一串1,起点l,终点r,由于必须从左向右

进行,其实相当于做了一次循环移动,变成了l,l+1,l+2.。。。r-1,r,l

于是我们在序列上做DP

因为是i与i + 1交换,i可以从i +  1转移过来,

为了方便计算, 我们用倒推。

dp[i][0]表示i这个位置放1,即第i个数与第i + 1个数交换,从i...n的最小代价

dp[i][1]表示i这个位置放0,即第i个数与第i + 1个数不交换,从i...n的最小代价

转移的时,0比较显然,1我们就枚举连续1的长度即可

有很多细节,转移详见代码

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <cstring>
5 #define max(a, b) ((a) > (b) ? (a) : (b))
6 #define min(a, b) ((a) < (b) ? (a) : (b))
7 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
8
9 inline void read(int &x)
10 {
11 x = 0;char ch = getchar(), c = ch;
12 while(ch < '0' || ch > '9')c = ch, ch = getchar();
13 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
14 if(c == '-')x = -x;
15 }
16
17 const int INF = 0x7fffffff;
18 const int MAXN = 10000 + 10;
19
20 int dp[MAXN][2], sum[MAXN], num[MAXN], n;
21
22 int main()
23 {
24 read(n);
25 for(register int i = 1;i <= n;++ i)
26 read(num[i]);
27 for(register int i = 2;i <= n;++ i)
28 sum[i] = sum[i - 1] + abs(num[i] - num[i - 1]);
29 for(register int i = n - 1;i >= 1;-- i)
30 {
31 if(i == n - 1)
32 dp[i][0] = abs(num[i + 1] - num[i]);
33 else
34 dp[i][0] = min(dp[i + 1][0] + abs(num[i] - num[i + 1]),
35 dp[i + 1][1] + abs(num[i] - num[i + 2]));
36 dp[i][1] = INF;
37 for(register int j = i + 1;j < n - 1;++ j)
38 {
39 dp[i][1] = min(dp[i][1],
40 abs(num[i] - num[j]) + sum[j] - sum[i + 1] +
41 min(dp[j + 1][0] + abs(num[i] - num[j + 1]),
42 dp[j + 1][1] + abs(num[i] - num[j + 2])));
43 }
44 if(i <= n - 2)
45 dp[i][1] = min(dp[i][1],
46 sum[n - 1] - sum[i + 1] + abs(num[i] - num[n - 1]) + abs(num[i] - num[n]));
47 dp[i][1] = min(dp[i][1],
48 sum[n] - sum[i + 1] + abs(num[n] - num[i]));
49 }
50 printf("%d", min(dp[1][0], dp[1][1]));
51 return 0;
52 }

T3

NOIP模拟17.9.22的更多相关文章

  1. NOIP模拟17.9.21

    NOIP模拟17.9.21 3 58 145 201 161.5 样例输出21.6 数据规模及约定对于40% 的数据,N <= 20对于60% 的数据,N <= 1000对于100% 的数 ...

  2. NOIP模拟 17.8.20

    NOIP模拟17.8.20 A.阶乘[题目描述]亲爱的xyx同学正在研究数学与阶乘的关系,但是他喜欢颓废,于是他就制作了一个和阶乘有关系的数学游戏:给出两个整数 n,m,令 t = !n,每轮游戏的流 ...

  3. NOIP模拟 17.8.18

    NOIP模拟17.8.18 A.小菜一碟的背包[题目描述]Blice和阿强巴是好朋友但萌萌哒Blice不擅长数学,所以阿强巴给了她一些奶牛做练习阿强巴有 n头奶牛,每头奶牛每天可以产一定量的奶,同时也 ...

  4. NOIP模拟 17.8.15

    NOIP模拟17.8.15 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  5. NOIP模拟 17.8.17

    NOIP模拟17.8.17 A 小 G 的字符串文件名 输入文件 输出文件 时间限制 空间限制str.pas/c/cpp str.in str.out 1s 128MB[题目描述]有一天,小 L 给小 ...

  6. NOIP模拟 17.8.16

    NOIP模拟17.8.16 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  7. NOIP模拟 17.8.14

    NOIP模拟17.8.14 (天宇哥哥考察细心程度的题) [样例解释]如果删去第一个 1:在[3,1,2]中有 3 个不同的数如果删去 3:在[1,1,2]中有 2 个不同的数如果删去第二个 1:在[ ...

  8. NOIP模拟 17.9.28

    公交车[问题描述]市内有

  9. Noip模拟17 2021.7.16

    我愿称这场考试为STL专练 T1 世界线 巧妙使用$bitset$当作vis数组使用,内存不会炸,操作还方便,的确是极好的. 但是这个题如果不开一半的$bitset$是会炸内存的,因为他能开得很大,但 ...

随机推荐

  1. vue基础知识总结

    vue不支持安卓6.0以下版本,切记!!! 1.创建vue实例 var vm = new Vue({ el: '#app', //所指向的dom的id data:{ }, //与dom元素绑定的数据 ...

  2. Http协议之content

    用android 通过http协议提交数据至服务器 content的内容 代码如下: private static JSONObject connUpload(String baseUrl, Map& ...

  3. 微信小程序连续旋转动画this.animation.rotate

    一..js中封装旋转动画方法 添加animation属性 data:{ animation:''" } 改变animation的值(官网提供角度范围是-180~180,但是我发现角度越大会一 ...

  4. uploadify附件上传 传参

    首先 在刚加载jsp时就加入上传方法,所以 formDate 中的参数 zFileName是页面刚加载时 exp1的值 ,后来通过js方法赋值不被读过来,如果 你想要获得这个值,可在 调用upload ...

  5. [COCI2019] Mobitel

    题目 显然不小于\(n\)这个东西我们不是很好搞,考虑正难则反,求出有多少条路径小于\(n\),之后拿\(C_{n+m}^m\)一减就好了 于是状态为\(dp[i][j][k]\)表示到\((i,j) ...

  6. Codeforces 442B. Andrey and Problem

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  7. C#墨攻IOC[转]

    原文叫看<墨攻>理解IOC概念 2006年多部贺岁大片以让人应接不暇的频率纷至沓来,其中张之亮的<墨攻>算是比较出彩的一部,讲述了战国时期墨家人革离帮助梁 国反抗赵国侵略的个人 ...

  8. JZOJ5883【NOIP2018模拟A组9.25】到不了——动态LCA裸题

    题目描述 Description wy 和 wjk 是好朋友. 今天他们在一起聊天,突然聊到了以前一起唱过的<到不了>. "说到到不了,我给你讲一个故事吧." &quo ...

  9. 网络流Sap算法

    GDKOi就快要开始了.没时间打解析,直接上模板. #include <cstdio> #include <cstring> #include <algorithm> ...

  10. Python开发第三方必备工具

      <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style=&quo ...