算法实验3《动态规划算法实验》

举报
用户已注销 发表于 2021/11/19 04:28:39 2021/11/19
【摘要】 1. 编写一个简单的程序,解决0-1背包问题。设N=5,C=10,w={2,2,6,5,4},v={6,3,5,4,6}  #include<iostream>using namespace std; void knapsack(int *v, int *w, int c, int n, int**m){ i...

1. 编写一个简单的程序,解决0-1背包问题。设N=5C=10,w={2,2,6,5,4},v={6,3,5,4,6} 


  
  1. #include<iostream>
  2. using namespace std;
  3. void knapsack(int *v, int *w, int c, int n, int**m)
  4. {
  5. int jmax = (w[n] > c) ? c : w[n]-1;
  6. for (int j = 0; j <= jmax; j++)m[n][j] = 0;
  7. for (int j = w[n]; j <= c; j++)m[n][j] = v[n];
  8. for (int i = n - 1; i > 1; i--)
  9. {
  10. jmax = (w[i] > c) ? c : w[i] - 1;
  11. for (int j = 0; j <= jmax; j++)m[i][j] = m[i + 1][j];
  12. for (int j = w[n]; j <= c; j++)
  13. m[i][j] = (m[i + 1][j] > m[i + 1][j - w[i]] + v[i]) ? m[i + 1][j] : m[i + 1][j - w[i]] + v[i];
  14. }
  15. m[1][c] = m[2][c];
  16. if (c >= w[1])m[1][c] = (m[1][c] > m[2][c - w[1]] + v[1]) ? m[1][c] : m[2][c - w[1]] + v[1];
  17. }
  18. int main()
  19. {
  20. int n = 5;
  21. int c = 10;
  22. int w[6] ={ 0, 2, 2, 6, 5, 4 };
  23. int v[6] = { 0, 6, 3, 5, 4, 6 };
  24. int **m = new int*[6];
  25. for (int i = 0; i < 6; i++)m[i] = new int[6];
  26. knapsack(v, w, c, n, m);
  27. cout << " 最优值为 " << m[1][c] <<"\n最优解为取第 ";
  28. for (int i = 1; i < n; i++)
  29. {
  30. if (m[i][c] != m[i + 1][c])
  31. {
  32. cout << i << " ";
  33. c -= w[i];
  34. }
  35. }
  36. if (m[n][c])cout << n;
  37. cout << " 个物品";
  38. system("pause>nul");
  39. return 0;
  40. }

2. 合唱队形安排问题

【问题描述】N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,  则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。


  
  1. #include<iostream>
  2. using namespace std;
  3. //计算以list[i]为结尾的递增数组的最大长度length[i]
  4. void getLength(int n, double *list, int *length)
  5. {
  6. length[0] = 0;
  7. for (int i = 1; i <= n; i++)
  8. {
  9. length[i] = 0;
  10. for(int j=0;j<i;j++)if(list[i]>list[j] && length[i]<length[j]+1)length[i] = length[j] + 1;
  11. }
  12. }
  13. void change(double *list, int n) //把数组反过来
  14. {
  15. for (int i = 1, j = n; i < j; i++, j--)
  16. {
  17. double s = list[i] + list[j];
  18. list[i] = s - list[i];
  19. list[j] = s - list[j];
  20. }
  21. }
  22. int main()
  23. {
  24. int n;
  25. cout << "输入n和n个正数\n";
  26. cin >> n;
  27. double *list = new double[n + 1];
  28. list[0] = 0;
  29. for (int i = 1; i <= n; i++)cin >> list[i];
  30. int *length1 = new int[n + 1], *length2 = new int[n + 1];
  31. getLength(n, list, length1);
  32. change(list, n);
  33. getLength(n, list, length2);
  34. int lengthmax = 0; //最大长度
  35. int index = 0; //最大长度对应的最大数的下标
  36. for (int i = 1; i <= n; i++)
  37. {
  38. if (length1[i] + length2[n + 1 - i] > lengthmax)
  39. {
  40. lengthmax = length1[i] + length2[n + 1 - i];
  41. index = i;
  42. }
  43. }
  44. cout << "合唱队形最大长度为" << lengthmax-1 << "\n最高者是第" <<index<<"个,高"<< list[index+1];
  45. system("pause>nul");
  46. return 0;
  47. }

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/78868583

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。