2020.10.16 19级training 补题报告

B - Power Sequence

 1.题意

  由n个正整数组成的序列,如果存在一个正整数c使得ai = c的i次方(0 <= i <= n - 1),这个序列就称为正确序列。允许的操作为①对序列排序②将序列中某个值加一或减一,这个操作代价为1。操作都可以进行无限次,求将给定序列变成正确序列所付出的最小代价。

 2.题解

  其实就是找到一个正整数c,使得ai - c的i次方的绝对值的和最小(0 <= i <= n - 1)。我们把序列按从小到大排序找出c肯定优于乱序找出c,数据范围不大,可以暴力枚举。如果我们令c等于1,这时我们付出的代价最大为1e5×1e9 = 1e14,我们把c从1枚举到1e14,当c的n次方超过1e14时,答案会劣于c为1的情况,因此我们只需把c从1枚举到1e14的1/n次方向下取整。

 3.代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn = 1e5 + 5;
 5 const ll INF = 1e14;
 6 int a[maxn];
 7 ll power[maxn];
 8 int main(){
 9     int n;
10     scanf("%d", &n);
11     for(int i = 1; i <= n; i++) {
12         scanf("%d", &a[i]);
13     } 
14     sort(a + 1, a + 1 + n);
15     int R = floor(pow(INF, 1.0 / n));
16     ll sum = 0;
17     ll ans=INF;
18     for(int i = 1; i <= R; i++) { 
19         sum = 0;
20         power[0] = 1;
21         for(int j = 1; j <= n; j++) {
22             power[j] = power[j-1] * i;
23             sum += abs(a[j] - power[j - 1]);
24         }
25         ans = min(ans, sum);
26     }
27     cout << ans << endl;
28     
29     return 0;
30 }
View Code

F - Basketball Exercise

 1.题意

  给定一个2*n的矩阵,按从左到右的顺序从中选择若干数,且选择的任意两个数上下不相邻且左右不相邻,求这些数的和最大是多少。

 2.题解

  注意到可以选择的球员编号是严格递增的,因此可以把状态的第一维定义为球员编号,第二维描述编号同为i的两名球员的选取情况。dp[i][0/1/2]表示选取了编号在i及以前的球员,所能得到的身高总和最大值。其中,第二维的0表示编号为i的球员一个都不选;1表示只选第一行的i号队员;i表示只选第二行的i号队员。

  状态转移方程:

  dp[i][0]=max{dp[i−1][0],dp[i−1][1],dp[i−1][2]}
  dp[i][1]=max{dp[i−1][0],dp[i−1][2]}+height[i][1]
  dp[i][2]=max{dp[i−1][0],dp[i−1][1]}+height[i][2]

  3.代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn = 1e5 + 5;
 5 int n;
 6 ll h[100005][3];
 7 ll dp[100005][3];
 8 int main() {
 9     scanf("%d", &n);
10     for(int i = 1; i <= n; i++) {
11         scanf("%lld", &h[i][1]);    
12     }
13     for (int i = 1; i <= n; i++) {
14         scanf("%lld", &h[i][2]);
15     }
16     dp[1][0] = 0;
17     dp[1][1] = h[1][1];
18     dp[1][2] = h[1][2];
19     for(int i = 2; i <= n; i++) {
20         dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1], dp[i - 1][2]));
21         dp[i][1] = max(dp[i - 1][0], dp[i - 1][2]) + h[i][1];
22         dp[i][2] = max(dp[i - 1][0], dp[i - 1][1]) + h[i][2];
23     }
24     printf("%lld
", max(dp[n][0], max(dp[n][1], dp[n][2])));
25     
26     return 0;
27 }
View Code
原文地址:https://www.cnblogs.com/lvguapi/p/13834689.html