题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257
这段时间在做专题训练,所以就刻意挑了挑动态规划做。
题目一看就知道是跟最长单调递减类似,简单的动态规划。
代码:
#include<stdio.h>//**dp[i]表示第i个导弹飞过来时需要的最少拦截装置.**// int main() { int n,i,j,max,h[10001],dp[10001]; while(~scanf("%d",&n)) { max=-1; dp[0]=0; for(i=1;i<=n;i++) { scanf("%d",&h[i]);//**飞来的高度**// dp[i]=1;//**初始化拦截装置都为1**// } for(i=1;i<=n;i++) { for(j=i-1;j>=0;j--) { if(h[i]>h[j]&&dp[i]<dp[j]+1)//**如果在拦截中出现了非单调递减的**// { dp[i]=dp[j]+1; } } } for(i=1;i<=n;i++) { if(dp[i]>max) { max=dp[i]; } } printf("%d\n",max); } return 0; }
其实在纸上写写就会发现以前导弹的最小记录按拦截记录来比较都是最小的。意思就是假如前面的拦截装置能够拦截就一定不需要判断后面的是否需要拦截,一定不需要拦截,依次类推(贪心);
代码:
#include<stdio.h> int main() { int n,x,i,j,min,count,flag,a[10001]; while(~scanf("%d",&n)) { count=0; for(i=1;i<=n;i++) { flag=0;//***标记元素**// scanf("%d",&x); min=30005; for(j=0;j<=count-1;j++) { if(a[j]>x&&min>a[j]-x)//**保证是和这个导弹最接近的**// { min=a[j]-x; a[j]=x; flag=1; } } if(flag==0) { a[count]=x; count++; } } printf("%d\n",count); } return 0; }还有一题差不多的,直接求单调递减的最大个数。
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=79
直接上代码:
#include<stdio.h> int main() { int s,n,i,j,max,h[101],dp[101]; scanf("%d",&s); while(s--) { max=-1; dp[0]=0; scanf("%d",&n); for(i=0;i<=n-1;i++) { scanf("%d",&h[i]); dp[i]=1; } for(i=1;i<=n-1;i++) { for(j=i-1;j>=0;j--) { if(h[i]<h[j]&&dp[i]<dp[j]+1) { dp[i]=dp[j]+1; } } } for(i=0;i<=n-1;i++) { if(dp[i]>max) { max=dp[i]; } } printf("%d\n",max); } return 0; }