1. 程式人生 > >Codeforces Round #523 (Div. 2) Solution

Codeforces Round #523 (Div. 2) Solution

A. Coins

Water.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n, s;
 4 
 5 int main()
 6 {
 7     while (scanf("%d%d", &n, &s) != EOF)
 8     {
 9         int res = 0;
10         for (int i = n; i >= 1; --i) while (s >= i) 
11         {
12             ++res;
13 s -= i; 14 } 15 printf("%d\n", res); 16 } 17 return 0; 18 }
View Code

 

 

B. Views Matter

Solved.

題意:

有n個棧,不受重力影響,在保持俯檢視以及側檢視不變的情況下,最多可以移掉多少個方塊

思路:

考慮原來那一列有的話那麼這一列至少有一個,然後貪心往高了放

 1 #include <bits/stdc++.h>
 2 using namespace
std; 3 4 #define ll long long 5 #define N 100010 6 int n, m; 7 ll a[N], sum; 8 9 int main() 10 { 11 while (scanf("%d%d", &n, &m) != EOF) 12 { 13 sum = 0; 14 for (int i = 1; i <= n; ++i) scanf("%lld", a + i), sum += a[i]; 15 sort(a + 1, a + 1 + n); 16 ll res = 0
, high = 0; 17 for (int i = 1; i <= n; ++i) if (a[i] > high) 18 ++high; 19 printf("%lld\n", sum - n - a[n] + high); 20 } 21 return 0; 22 }
View Code

 

C. Multiplicity

Upsolved.

題意:

定義一個序列為好的序列即$b_1, b_2, ...., b_k 中i \in [1, k] 使得 b_i % i == 0$

求有多少個好的子序列

思路:

考慮$Dp$

$令dp[i][j] 表示第i個數,長度為j的序列有多少種方式$

$dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]   (arr[j] % j == 0)$

否則 $dp[i][j] = dp[i - 1][j]$

然後不能暴力遞推,只需要更新$arr[j] % j == 0 的j即可$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1000100
 6 const ll MOD = (ll)1e9 + 7;
 7 int n; ll a[N], dp[N];
 8 
 9 int main()
10 {
11     while (scanf("%d", &n) != EOF)
12     {
13         for (int i = 1; i <= n; ++i) scanf("%lld", a + i);
14         memset(dp, 0, sizeof dp);
15         dp[0] = 1;    
16         for (int i = 1; i <= n; ++i)
17         {
18             vector <int> cur;
19             for (int j = 1; j * j <= a[i]; ++j)
20             {
21                 if (a[i] % j == 0)
22                 {
23                     cur.push_back(j);
24                     if (j != a[i] / j)
25                         cur.push_back(a[i] / j);
26                 }
27             }
28             sort(cur.begin(), cur.end());
29             reverse(cur.begin(), cur.end());
30             for (auto it : cur)
31                 dp[it] = (dp[it] + dp[it - 1]) % MOD;
32         }
33         ll res = 0;
34         for (int i = 1; i <= 1000000; ++i) res = (res + dp[i]) % MOD;
35         printf("%lld\n", res);    
36     }
37     return 0;
38 }
View Code

 

D. TV Shows

Upsolved.

題意:

有n個電視節目,每個節目播放的時間是$[l, r],租用一臺電視機的費用為x + y \cdot time$

一臺電視機同時只能看一個電視節目,求看完所有電視節目最少花費

思路:

貪心。

因為租用電視機的初始費用是相同的,那麼我們將電視節目將左端點排序後

每次選擇已經租用的電視機中上次放映時間離自己最近的,還要比較租用新電視機的費用,

如果是剛開始或者沒有一臺電視機閒著,則需要租用新的電視機

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 100010
 6 struct node
 7 {
 8     ll l, r;
 9     void scan() { scanf("%lld%lld", &l, &r); }
10     bool operator < (const node &r) const 
11     {
12         return l < r.l || (l == r.l && this->r < r.r);
13     }
14 }arr[N];
15 int n; ll x, y;
16 const ll MOD = (ll)1e9 + 7;
17 multiset <ll> se;
18 
19 int main()
20 {
21     while (scanf("%d%lld%lld", &n, &x, &y) != EOF) 
22     {
23         for (int i = 1; i <= n; ++i) arr[i].scan();
24         sort(arr + 1, arr + 1 + n);
25         ll res = 0;
26         for (int i = 1; i <= n; ++i)
27         {
28             if (se.lower_bound(arr[i].l) == se.begin())
29                 res = (res + x + y * (arr[i].r - arr[i].l) % MOD) % MOD;
30             else
31             {
32                 int pos = *(--se.lower_bound(arr[i].l)); 
33                 if (x < y * (arr[i].l - pos)) 
34                     res = (res + x + y * (arr[i].r - arr[i].l) % MOD) % MOD;
35                 else
36                 {
37                     se.erase(--se.lower_bound(arr[i].l));
38                     res = (res + y * (arr[i].r - pos) % MOD) % MOD; 
39                 }    
40             }
41             se.insert(arr[i].r); 
42         }
43         printf("%lld\n", res);
44     }
45     return 0;
46 }
View Code

 

E. Politics

Unsolved.

 

F. Lost Root

Unsolved.