0


2022-03-17每日刷题打卡

2022-03-17每日刷题打卡

力扣春季赛开始啦,佬们求求给战队点个赞吧:啊哈哈哈AC来咯

代码源——每日一题

快快变大 - 题目 - Daimayuan Online Judge

给定一个长度为 n 的数组 a1,a2,…,an,接下来进行 n−1 次操作。每次选择一个下标 xx ,将 ax 和 ax+1 合并成 (ax)×(ax+1)mod1000003 ,并且你会获得 (ax−ax+1)^2 的分数。

所以每次操作后,数组的长度将会减 1,当最后只剩下一个元素时停止操作。输出最终能获得的最大分数。

输入格式

第一行一个数字 n。

接下来一行 n 个整数 a1,a2,…,an。

输出格式

一个数,表示答案。

样例输入

  1. 3
  2. 1 2 3

样例输出

  1. 26

数据规模

所有数据保证 1≤n≤300,1≤ai≤10^6

今天这道题其实是我投的哦哼哼哼(叉腰)。

区间dp,这题做法和石子合并 - 题目 - Daimayuan Online Judge基本一样,如果没写过石子合并题可以来2月14每日打卡-CSDN博客这看下我以前写的题解。

我们先用一个二维数组预处理下各个区间的乘积和,s[i] [j]的意思是ai到aj的乘积。用一个二维动规数组f来做区间dp,dp[i] [j]意思是合并i到j可以得到的最大分数。然后我们从长度2开始枚举区间长度,来获得每个区间所能得到的最大分数。最后答案就是dp[1] [n],状态转移方程:

  1. f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + (s[i][k]-s[k+1][j])* (s[i][k] - s[k + 1][j]));
  1. #include<iostream>
  2. using namespace std;
  3. #include<vector>
  4. #include<algorithm>
  5. #include<math.h>
  6. #include<set>
  7. #include<numeric>
  8. #include<string>
  9. #include<string.h>
  10. #include<map>
  11. #include<unordered_map>
  12. #include<stack>
  13. #include<list>
  14. #include<queue>
  15. #pragma GCC optimize(1)
  16. #pragma GCC optimize(2)
  17. #pragma GCC optimize(3,"Ofast","inline")
  18. typedef long long ll;
  19. typedef pair<ll, ll>PII;
  20. const int N = 1010, MOD = 1000003;
  21. ll f[N][N], s[N][N],v[N];
  22. int main()
  23. {
  24. int n;
  25. cin >> n;
  26. for (int i = 1; i <= n; i++)
  27. {
  28. cin >> v[i];
  29. }
  30. for (int i = 1; i <= n; i++)
  31. {
  32. s[i][i] = 1;
  33. s[i][i-1] = 1;
  34. for (int j = i; j <= n; j++)
  35. {
  36. s[i][j] = (v[j] * s[i][j - 1]) % MOD;
  37. }
  38. }
  39. for (int len = 2; len <= n; len++)
  40. {
  41. for (int i = 1; i + len - 1 <= n; i++)
  42. {
  43. int j = i + len - 1;
  44. for (int k = i; k < j; k++)
  45. {
  46. f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + (s[i][k]-s[k+1][j])* (s[i][k] - s[k + 1][j]));
  47. }
  48. }
  49. }
  50. cout << f[1][n] << endl;
  51. return 0;
  52. }

飞书——每日一题

153. 寻找旋转排序数组中的最小值

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

我们已经知道了,数组原本是有序的,但是经过了旋转变换。经过变换后数组实际上还是有序的,但是是分成了两部分,比如样例给的3 4 5 1 2,原本是1 2 3 4 5,经过旋转后变成了3 4 5 1 2,但我们把它分成两部分后就可以发现,35仍然是有序的,12也是有序的,我们可以找到两个相邻的点,使得数组从他们中间分成两个有序的部分,而这两个个分界点就是数组的最大值和最小值。我们可以用二分来找这两个点。

我们可以先取中间的点,然后看左半边是否是递增序,如果有序,就说明我们要找到点不在左半边,反之在左半边。就这样一直二分,最后找到的就是我们要的分界点了。

比如 5 6 7 8 9 1 3,我们第一次取得中点是8,左边是58,是递增有序的,右边是83,不是递增的,说明分界点在右边,然后我们再找点就是9,再看左边是有序右边无序,再去右边找;下个点是1,右边有序左边无序,去左边找,最后找到的就是我们要的点了。(二分写的不习惯,我找到的是最大值,但因为最大值和最小值挨着,所有我可以在最大值后面找到最小值,如果佬们二分写的好一个不会有这问题,毕竟思路没问题)

  1. class Solution {
  2. public:
  3. int findMin(vector<int>& nums) {
  4. int n=nums.size();
  5. int l=0,r=n-1;
  6. if(n==1||nums[(n-1)]>nums[0])return nums[0];
  7. else
  8. {
  9. while(l<r)
  10. {
  11. int mid=(l+r)/2;
  12. if(nums[l]<nums[mid])l=mid;
  13. else r=mid;
  14. }
  15. }
  16. return nums[l+1];
  17. }
  18. };

力扣——每日一题

720. 词典中最长的单词 - 力扣(LeetCode) (leetcode-cn.com)

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。

若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

示例 1:

输入:words = [“w”,“wo”,“wor”,“worl”, “world”]
输出:“world”
解释: 单词"world"可由"w", “wo”, “wor”, 和 "worl"逐步添加一个字母组成。

我们先用哈希表记录每个单词的出现情况,然后再遍历数组枚举每个字符,并且把每个字符从尾部开始一个个去掉字母,每次去掉都判断是否在哈希表有记录,如果知道拆完都有记录那就说明这个字符串符合条件,然后记录下来,并在此过程中维护最长,字典序最小的那个。

  1. class Solution {
  2. public:
  3. string longestWord(vector<string>& words) {
  4. unordered_map<string,int>mymap;
  5. string str;
  6. for(auto i:words)
  7. mymap[i]++;
  8. for(auto i:words)
  9. {
  10. if(i.size()>=str.size())
  11. {
  12. bool flag=true;
  13. string s=i;
  14. s.pop_back();
  15. while(s.size()!=0&&flag)
  16. {
  17. if(mymap[s]==0)
  18. {
  19. flag=false;
  20. }
  21. s.pop_back();
  22. }
  23. if(flag)
  24. {
  25. if(i.size()>str.size())str=i;
  26. else str=i>str?str:i;
  27. }
  28. }
  29. }
  30. return str;
  31. }
  32. };
标签: 动态规划 算法 c++

本文转载自: https://blog.csdn.net/fnmdpnmsl/article/details/123546962
版权归原作者 你好_Ä 所有, 如有侵权,请联系我们删除。

“2022-03-17每日刷题打卡”的评论:

还没有评论