第三章算法作业(求助攻)

3-1.LIS(longest increas sequence)不多说,题目说了要($ O(n^2) $),我还能说什么呢?

  相同题目:HDU 1087 super jumping !jumping!jumping! 而且不卡平方的做法

  用dp[i]表示以 i 个数结尾的序列的LIS长度,初始化为dp[i] = 1 ($ 1 \leq i \leq n $)下面附一神代码

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <algorithm>
 4 using namespace std;
 5 int num[5005],d[5005];
 6
 7 int main(void)
 8 {
 9     int n; cin>>n;
10     for(int i=0;i<n;i++) scanf("%d",num+i);
11     for(int i=0;i<n;i++)
12     {
13         d[i]=1;
14         for(int j=0;j<i;j++)
15             if(num[j]<=num[i]) d[i]=max(d[i],d[j]+1);
16     }
17     int ans=0;
18     for(int i=0;i<n;i++) ans=max(ans,d[i]);
19     printf("%d\n",ans);
20     return 0;
21 }

Aguin

3-2. 依旧LIS,不过要求 $ O(log(n)) $的算法。

  用 dp[cnt]保存长度为cnt的LIS中最后一个数最小的那个数,刚开始,dp[1]为序列中最小的数,对于 num[i]($ 2 \leq i $),如果num[i] > dp[1] ,则dp[2] = num[i],否则,在dp数组中找到比num[i]大的数中最小的那个数(dp数组是有序的,直接二分就ok)更新dp数组:dp[找到的位置] = num[i],最后cnt就是答案啊!

  相同题目:NYOJ 17 单调递增最长子序列 很棒的一个题目,平方做法不能AC

  

 1
 2 /*************************************************************************
 3     > File Name: lis.cpp
 4     > Author:
 5     > Mail:
 6     > Created Time: 2016年03月27日 星期日 20时59分03秒
 7  ************************************************************************/
 8
 9 #include <iostream>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <cstring>
13 #include <algorithm>
14 #include <cmath>
15
16 using namespace std;
17 const int maxn = 10010 ;
18 char s[maxn] , d[maxn] ;
19
20 inline int reads()
21 {
22     int i = 0 ;
23     char c = getchar() ;
24     if (c == ‘\n‘) c = getchar() ;
25     while (c != ‘\n‘) {
26         s[++i] = c ;
27         c = getchar() ;
28     }
29     return i ;
30 }
31
32 int main()
33 {
34  //   freopen("in","r",stdin) ;
35     int T , len ;
36     scanf("%d",&T) ;
37     while (T --) {
38         len = reads() ;
39         d[1] = s[1] ;
40         int cnt = 1 ;
41         for (int i = 2 ; i <= len ; ++ i) {
42             if (s[i] > d[cnt]) d[++cnt] = s[i] ;
43             else {
44                 int pos = lower_bound(d+1,d+1+cnt,s[i]) - d ;
45                 d[pos] = s[i] ;
46             }
47         }
48         printf("%d\n",cnt) ;
49     }
50     return 0 ;
51 }

CROSShh

3-3. 题意:有两台机器处理N个任务,任务i在如果机器A上处理要花$ a_{i} $时间,在B花$ b_{i} $时间,两台机器可以同时工作,同一个任务只处理一次即可。求最少要花多长时间处理所有任务。

  任务 i 要么在 A 处理,要么在 B 处理,我们考虑前 i-1 个任务已经处理了,机器 A 的结束时间为 TimeA , 机器 B 的结束时间为 TimeB,那么,

  1. 在 A 处理总的结束时间为 max(TimeA+$ a_{i} $,TimeB}。
  2. 在 B 处理总的结束时间为 max(TimeB+$ b_{i} $,TimeA}。

  当然选最小的啦(对于第一个任务来说TimeA=TimeB=0)。代码略==有空再写吧!

3-4. 题意:设有 N 种不同面值的硬币,记为T[i],现在用这些硬币来找钱,各种硬币个数不限

  Q_A:当只用前 i 个硬币时,可以找出钱数 j 的最少硬币个数记为C(i,j),找不出则C(i,j) = 无穷大,给出C(i,j)的递归表达式和初始条件。1 << i << N , 1 <= j <= L ;

  Q_B: 设计算法,对于1 <= j <= L,计算出C(n,j),只允许用数组L,T,并给出时间复杂度

  Q_C: 在C(n,j)已知的情况下,设计贪心算法,对钱数 m (m <= L)给出求C(n,m)的办法,时间复杂度应为O(n+C(n,m))

3-5. 用 "<" , "=",把三个数A,B,C依序排列,有13种不同的序关系

  A = B = C , A = B < C , A < B = C , A < B < C , A < C < B

  A = C < B , B < A = C , B < A < C ,B < C < A , B = C < A

  C < A = B , C < A < B,C < B < A

现在有 n 个数,问有多少种序关系(时间复杂度要求O(n^2),空间复杂度要求O(n))

3-6. 暂无

3-7. 暂无

3-8. 题意:给出A,B两个字符串,目的是把转换成B,问最小的操作次数,满足以下三种操作:

  1. 删除一个字符
  2. 插入一个字符
  3. 把一个字符变成另一个字符

题目说的操作我理解为只能对A操作,那么,必须要满足:

  1. 能不操作的就尽量不操作
  2. 能改变的就不使用删除和插入操作

所以,答案就是max(A.length,B.length) - LCSlength(A,B).

3-9. 题意:经典的石子合并问题,可以用四边形优化到平方

  参考链接:ACdreamer石子合并问题

  和矩阵连乘是同样的类型:dp[i][j] = max(dp[i][k] + dp[k+1][j]+sum[i][j])。sum[i][j] 表示从 i 到 j 的石子的总个数

  我更青睐于在最后一堆石子后面添加 N 堆石子,这样只需要找到max(dp[i][i+N-1]),也是一样的。

3-10. 题意:数塔(数字三角形)

  自顶向上递推即可dp[i][j] += max(dp[i+1][j],dp[i+1][j+1]),注意一下边界

3-11. 题意:完全背包

  参考链接:背包九讲  (提取码:d16f)

for i = 1 ; i <= N ; ++ i
for v = cost[i] ; v <= vmax ; v ++
dp[v] = max(dp[v],dp[v-v[i]]+value[i])

  

3-12. 题意:二维费用的背包,上个题目的资料中有!

  dp[i][v][d] = max(dp[i-1][v][d],dp[i][v-v[i]][d-d[i]] + val[i])

3-13. 给了一个特殊的乘法表:

  

== a b c
a b b a
b c b a
c a c c

即:aa = b,ab = b ,ac = a , ba = c,bb = b ,bc = a,ca = a,cb = c,cc = c;

  让干的是:给出一个由abc组成的字符串,问加括号后最终是 a 的方案数.类似矩阵连乘

  dp[a][i][j] = dp[a][i][k]*dp[c][k+1][j] + dp[b][i][k]*dp[c][k+1][j] + dp[c][i][k] + dp[a][k+1][j]

  dp[b][i][j] = dp[a][i][k]*dp[a][k+1][j] + dp[a][i][k]*dp[b][k+1][j] + dp[b][i][k]*dp[b][k+1][j]

  dp[c][i][j] = dp[b][i][k]*dp[a][k+1][j] + dp[c][i][k]*dp[b][k+1][j] + dp[c][i][k]*dp[c][k+1][j]

3-14. 暂无

3-15. 暂无

3-16. 给定一个N*N的网格,左上角为起点 S (1,1),一辆汽车要从左上角走到右下角(只能走网格边),遵循以下规则:

  1. 满油能走的距离是 K ,
  2. 若逆向(X 或 Y 坐标减小)行驶花费 B
  3. 遇油库就加满油,花费 A
  4. 可以任意增设油库,花费 C (不含加油费)

目的是从左上角走到右下角且花费最小.

dis[i][j]表示从上次满油状态走到位置(i,j)的距离

dp[i][j] 表示走到位置(i,j)的最小花费.

dp[i][j] = min(dp[i][j-1],dp[i-1][j],dp[i+1][j] + B,dp[i][j+1] + B) ;

dis[i][j] = dis[x][y] ++ ;//x , y 为dp中选择的i,j

if (i,j) 是个油库,dp[i][j] += A , dis[i][j] = 0 ;

else if dis[i][j] == k {

  //新建油库且加油

  dp[i][j] += (A+C)

  dis[i][j] = 0 ;

}

3-17. 题意:给定一个 M*N 的网格,目的是从左上角到右下角,网格边有权值,某些网格点处有障碍物不能走,设计算法,求路径的最小权值和

  类似3-16,不能走设为无穷大,

  if (dp[i][j] == inf) continue;

  else dp[i][j] = min(dp[i][j-1] + val[][],dp[i][j+1]+val[][],dp[i-1][j]+val[][],dp[i+1][j]+val[][])

3-18. 关于整数的二元运算符"#"定义为:

(X # Y) = 十进制整数 X 的各位数字之和 * 十进制整数 Y 中最大的数字 + Y 中的最小数字

例如:(9 # 30) = 9*3 + 0 = 27;

  问题:对于给定的十进制整数 X 和 K,由X 和 #运算可以组成各种不同的表达式,计算由 X 和 # 运算组成的值为 K 的表达式至少需要多少个 #

    

~end~

时间: 2025-01-12 22:53:14

第三章算法作业(求助攻)的相关文章

Python算法教程第三章知识点:求和式、递归式、侏儒排序法和并归排序法

本文目录:一.求和式:二.递归式:三.侏儒排序法和并归排序法微信公众号:geekkr</br></br></br> 一.求和式 # 假设有一函数为f(),则在Python中经常使用的求和方法如下. sum(f(i) for i in range(m, n+1)) + sum(g(i) for i in range(m, n+1)) sum(f(i)+g(i) for i in range(m, n+1)) </br>二.递归式 # 举个栗子 def S(se

第三章算法设计题

3.2.8 /***循环队列基本操作***/ #include<cstdlib> #include<iostream> #include<fstream> using namespace std; #define MAXQSIZE 100 #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int QElemType; typedef int Status; typedef struct { QElemTyp

第三章家庭作业

小组成员:20135310陈巧然 20135305姚歌 选题:3.56 分值:2分 题目: 解题思路及答案: A. 寄存器 变量esi    xebx    nedi    resultedx    mask B. result:0x55555555 mask:0x80000000 C. mask !=0 D. 第十行,逻辑右移了n位 E. 第八行,result ^= (mask & x) F. int loop(int x, int n) {    int result = 0x5555555

第三章家庭作业3.65

我们可以从题目所给的汇编代码画出结构体变量的栈结构. 我们从汇编代码中可以看到 由变量t和u相差16个地址值可知,short s[B]存放在16个字节中,而一个short型变量在内存中占用2个字节,所以我们可以推断出, B取四的倍数的上整数 = 8. 8+4+ (B*2)取四的倍数的上整数 = 28. 所以B的可选值为8和7. 2*A*B取四的上整数为44,所以A*B的可选值为21和22. 所以 A=3, B=7.

第三章家庭作业 3.65

解: B取四的倍数的上整数 = 8 8+4+ (B*2)取四的倍数的上整数 = 28 ∴ B的可选值为8和7 2*A*B取四的上整数为44 ∴ A*B的可选值为21和22 ∴ A=3, B=7

《计算机科学导论》第三章课后作业解答(个人版)

1.说出5种计算机可以处理的数据. 数字.文本.音频.图像和视频. 2.位模式的长度如何与其能表示的符号数量相关? 若位模式的长度为n,则其能表示的符号数量为2n. 3.位图方法是如何以位模式来表示一个图像的? 一张图像由模拟数据组成,数据密度(色彩)因空间变化,意味着数据需要采样.样本被称为像素,换言之,整个图像被分成小的像素,每个像素有单独的密度值,而该值由位模式表示. 4.矢量图方法优先于位图方法的优点是什么?其缺点又是什么? 矢量图图像编码方法并不存储每个像素的位模式.一个图像被分解成几

家庭作业——第三章

第三章家庭作业    3.69和3.70 3.69 A:long trace(tree_ptr tp)    {        long ret = 0;        while(tp != NULL)        {           ret = tp->val;           tp = tp->left;        }        return ret;    } B:作用是从根一直遍历左子树,找到第一个没有左子树的节点的值. 3.70 A:long traverse(t

算法竞赛入门经典第二版第三章习题

写这个的原因是看到一位大神的习题答案总结,于是自己心血来潮也想写一个这个,目的主要是督促自己刷题吧,毕竟自己太弱了. 习题3-1 得分 UVa 1585 大致就是设置一个变量记录到当前为止的连续的O的数量,碰到X就变0,水题. #include<stdio.h> #include<ctype.h> #include<string.h> char s[90]; int main(void) { int length,n,sum,num; scanf("%d&qu

揭露动态规划真面目——算法第三章上机实践报告

算法第三章上机实践报告 一.        实践题目 7-2 最大子段和 (40 分) 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值.当所给的整数均为负数时,定义子段和为0. 要求算法的时间复杂度为O(n). 输入格式: 输入有两行: 第一行是n值(1<=n<=10000): 第二行是n个整数. 输出格式: 输出最大子段和. 输入样例: 在这里给出一组输入.例如: 6 -2 11 -4 13 -5