HDU1257:最少拦截系统
HDU1257:最少拦截系统
kuangbin专题十二:I 题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 46186 Accepted Submission(s): 18198
Problem Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.
Input
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
Output
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.
Sample Input
8 389 207 155 300 299 170 158 65
Sample Output
2
贪心:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std ; #define maxn 100000 int n , total ; int num[maxn] ; bool flag ; int num1 ; int main(){ while(~scanf("%d" , &n)){ memset(num , 0 , sizeof(num)) ; total = 0 ; for(int i=1 ; i<=n ; i++){ scanf("%d" , &num1) ; flag = false ; for(int i=0 ; i<total ; i++){ if(num[i] > num1 ){ // 每次 用最小高度 炮 拦截 , 拦截不了就 添加一个炮 flag = true ; num[i] = num1 ; break ; } } if(!flag){ num[total++] = num1 ; } } printf("%d\n" , total) ; } return 0 ; }
动规:
//////////////////////////////// 动态规划 另外: 刚开始以为只要一遍一遍的找最长非递增数列就行了,第一遍找出来最长的,然后把这一列里面的数字去掉, 在剩下来的里面继续前面的操作就行了,直到所有元素都被去掉,然后发现碰到这种情况就不行了 9 5 1 8 4 2 第一次去掉9 5 4 2, 然后去掉1,最后去掉8,就是说要三次,其实只要两次 :第一次9 5 1 , 第二次8 4 2; #include<stdio.h> #include<string.h> // 两个状态 #include<math.h> // dp[i] = max( dp[i] , dp[j] + 1 ); 选 a[i] 和 不选a[i] #include <iostream> #include <algorithm> using namespace std; int N,sum=0; int a[200010],dp[200010]; int main() { while(cin>>N) { // memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); int numbs=0; for(int i=1;i<=N;i++) { cin>>a[i]; } for(int i=1;i<=N;i++) { for(int j=i-1;j>=0;j--) { if(a[i]>a[j]) { dp[i]=max(dp[i],dp[j]+1); // 仔细想想为什么是选 最大的 } } if(numbs<dp[i]) numbs=dp[i]; } cout<<numbs<<endl; } return 0; }