编程练手——动态规划

1481:Maximum sum

题目:http://noi.openjudge.cn/ch0206/1481/ 总时间限制: 
1000ms
内存限制: 
65536kB
描述
Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:
                     t1     t2 
d(A) = max{ ∑ai + ∑aj | 1 <= s1 <= t1 < s2 <= t2 <= n }
i=s1 j=s2

Your task is to calculate d(A).
输入
The input consists of T(<=30) test cases. The number of test cases (T) is given in the first line of the input. 
Each test case contains two lines. The first line is an integer n(2<=n<=50000). The second line contains n integers: a1, a2, ..., an. (|ai| <= 10000).There is an empty line after each case.
输出
Print exactly one line for each test case. The line should contain the integer d(A).
样例输入
1

10
1 -1 2 2 3 -3 4 -4 5 -5
样例输出
13
提示
In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer.

Huge input,scanf is recommended.
来源
POJ Contest,Author:Mathematica@ZSU
 1 #include <cstdio>
 2 #include <algorithm>//max()函数
 3 using namespace std;
 4 int T, n, num[50050], r_max[50050], l_max[50050], ans;
 5 int main(){
 6     scanf("%d", &T);
 7     while(T--){
 8         scanf("%d", &n);
 9         //初始化
10         for(int i=0; i<n; ++i){
11             scanf("%d", &num[i]);
12             r_max[i] = l_max[i] = -10050;
13             ans = -20100;
14         }
15         //求以第i个数为结束的最大和子串
16         l_max[0] = num[0];
17         for(int i=1; i<n; ++i)
18             l_max[i] = max(l_max[i-1] + num[i], num[i]);
19         //求以第i个数为开始的最大和子串
20         r_max[n-1] = num[n-1];
21         for(int i=n-2; i>=0; --i)
22             r_max[i] = max(r_max[i+1] + num[i], num[i]);
23         //求以第i个数及之前的最大和子串
24         for(int i=1; i<n; ++i)
25             l_max[i] = max(l_max[i-1], l_max[i]);
26         //求以第i个数及之后的最大和子串
27         for(int i=n-2; i>=0; --i)
28             r_max[i] = max(r_max[i+1], r_max[i]);
29         //求以第i个数为分割的两个子串和最大和
30         for(int i=0; i<n-1; i++)
31             ans = max(ans, l_max[i] + r_max[i+1]);
32         printf("%d\n", ans);
33     }
34     return 0;
35 }
View Code

我的代码

 

 

2988:计算字符串距离

总时间限制: 
1000ms
内存限制: 
65536kB
描述
对于两个不同的字符串,我们有一套操作方法来把他们变得相同,具体方法为:
  1. 修改一个字符(如把“a”替换为“b”)
  2. 删除一个字符(如把“traveling”变为“travelng”)

比如对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。无论增加还是减少“g”,我们都仅仅需要一次操作。我们把这个操作所需要的次数定义为两个字符串的距离。 
给定任意两个字符串,写出一个算法来计算出他们的距离。
输入
第一行有一个整数n。表示测试数据的组数,
接下来共n行,每行两个字符串,用空格隔开。表示要计算距离的两个字符串
字符串长度不超过1000。
输出
针对每一组测试数据输出一个整数,值为两个字符串的距离。
样例输入
3
abcdefg  abcdef
ab ab
mnklj jlknm
样例输出
1
0
4

我的代码

 1 /*
 2  2019年9月27日
 3  OJ-2988:计算字符串距离
 4  */
 5 #include <stdio.h>
 6 #include <string.h>
 7 using namespace std;
 8 //记录字符串s1[0,...,l1-1]与字符串s2[0,...,l2-1]的最短距离
 9 int m[1010][1010];
10 //求最小值
11 int myMin(int a, int b, int c){
12     return a<b?(a<c?a:c):(b<c?b:c);
13 }
14 //m[][]初始化
15 void m_ini(){
16     for(int i=0; i<=1000; ++i)
17         m[i][0] = i;
18     for(int j=0; j<=1000; ++j)
19         m[0][j] = j;
20 }
21 //递推
22 void m_recur(int l1, int l2, char * s1, char * s2){
23     for(int i=1; i<=l1; ++i)
24         for(int j=1; j<=l2; ++j)
25             //如果字符串s1[0,...,l1-1]与s2[0,...,l2-1]的最后一个字符相同
26             if(s1[i-1] == s2[j-1])
27                 m[i][j] = m[i-1][j-1];
28             //删除s1[l1-1]、删除s2[l2-1]、替换s1[l1-1]或s2[l2-1]
29             else
30                 m[i][j] = 1 + myMin(m[i-1][j], m[i][j-1], m[i-1][j-1]);
31 }
32 int main() {
33     int n, l1, l2;
34     char s1[1010], s2[1010];
35     m_ini();//m[][]初始化
36     scanf("%d", &n);
37     while(n--){
38         scanf("%s %s", s1,s2);
39         l1 = (int)strlen(s1);
40         l2 = (int)strlen(s2);
41         m_recur(l1, l2, s1, s2);//递推
42         printf("%d\n", m[l1][l2]);
43     }
44     return 0;
45 }
View Code

 

转载于:https://www.cnblogs.com/tanshiyin-20001111/p/11525710.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值