当前位置:   article > 正文

动态规划- 【气球游戏】

动态规划- 【气球游戏】
  1. 题目:【气球游戏】小Q在进行射击气球的游戏,如果小Q在连续T枪中打爆了所有颜色的气球,将得到一只QQ公仔作为奖励。(每种颜色的气球至少被打爆一只)。这个游戏中有m种不同颜色的气球,编号1到m。小Q一共有n发子弹,然后连续开了n枪。小Q想知道在这n枪中,打爆所有颜色的气球最少用了连续几枪?
  2. 输入描述:
  3. 第一行两个空格间隔的整数数n,m。n<=1000000 m<=2000
  4. 第二行一共n个空格间隔的整数,分别表示每一枪打中的气球的颜色,0表示没打中任何颜色的气球。
  5. 输出描述:
  6. 一个整数表示小Q打爆所有颜色气球用的最少枪数。如果小Q无法在这n枪打爆所有颜色的气球,则输出-1
  7. 示例
  8. 输入:
  9. 12 5
  10. 2 5 3 1 3 2 4 1 0 5 4 3
  11. 输出:
  12. 6

二、思路:

1.暴力求解:冒泡排序的方式遍历击中气球序列arr_ball[2000],对每个子串i...j范围进行判断是否击中所有颜色气球,全部击中所有颜色则赋值击中次数shut_cnt。复杂度o(n^3)

2.对问题进行抽象:个人认为分两步

1)找出所有包含1~m数字的子数组序列,这种序列的特点是子数组的和大于等于 (1+...+m)且包含1...m数字,可以抽象成求数组序列子段和大于某一阈值问题。

2)找出子数组长度最短的序列长度。

 

暴力求解代码c++: 

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. using namespace std;
  5. // 返回是否击中所有颜色,赋值击中次数shut_cnt
  6. bool loop_m(int i,int j ,int arr_ball[],int m,int &shut_cnt)
  7. {
  8. int sum_m=0,is_shut=1;
  9. int tmp_m[200]={0};
  10. for(int k=i;k<=j;k++)
  11. {
  12. //没有击中任何颜色,设计次数+1
  13. if(arr_ball[k]==0 ) sum_m=1;
  14. else tmp_m[arr_ball[k]-1]+=1;
  15. }
  16. for(int j=0;j<m;j++)
  17. {
  18. //命中次数
  19. sum_m+=tmp_m[j];
  20. //是否所有颜色命中,如果有遗漏则,则该组命中次数设置为0
  21. if(tmp_m[j]==0) is_shut=0;
  22. }
  23. shut_cnt+=sum_m;
  24. return is_shut!=0 ? true : false ;
  25. }
  26. int is_vector(int n,int m, int arr_ball[])
  27. {
  28. int i=0,j=0,cur_min=0,min=10000;
  29. //for(int i=0;i<m;i++) i+=tmp_m[i]; //memset(&tmp_m,0,sizeof(tmp_m));
  30. for( i=0 ;i<n-1;i++)
  31. {
  32. for(j=i+1;j<n;j++)
  33. {
  34. //长度>=m的子序列
  35. if(j-i+1>=m)
  36. { //当前击中次数
  37. cur_min=0;
  38. //子序列中是否有满足击中所有颜色气球
  39. if(loop_m(i,j,arr_ball,m,cur_min)==true)
  40. {
  41. if(cur_min<min)
  42. min=cur_min;}
  43. }
  44. }
  45. }
  46. }
  47. return (min >=m && min!=10000)? min : -1 ;
  48. }
  49. int main() {
  50. int n,m,arr_ball[2000];
  51. cin >> n>> m;
  52. for(int i=0;i<n;i++) cin>>arr_ball[i];
  53. cout << is_vector(n,m,arr_ball) << endl;
  54. }

结果:

测试用例1

12 5
2 5 3 1 3 2 4 1 0 5 4 3

结果:

测试用例2:

12 5
2 5 3 1 4 2 4 1 0 5 4 3

结果:

测试用例3:

12 5
2 5 3 3 4 2 4 3 0 5 4 3

结果:

 

结果:

   若使用子段和问题的方法,就是动态规划问题,复杂度可降为O(n)。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/491569
推荐阅读
相关标签
  

闽ICP备14008679号