【HDU】 1257 最少拦截系统
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257
网上很多说法是贪心,但我更支持DP,而且是最长不降子序列的题目的变形,这里推荐一个做法:http://blog.csdn.net/calvin_zcx/article/details/7333923
根据他的做法来解读下(也欣赏下写的很不错的代码):
1 int LIS(int *ary, int n) 2 { 3 int i, j, m; 4 dp[1] = 1; 5 for(i = 2; i <= n; i++) 6 { 7 m = 0; 8 for(j = 1; j < i; j++) //最长不降子序列的经典做法,两重循环枚举 9 { 10 if(ary[i] > ary[j] && dp[j] > m) //如果在i之前发现比他矮的j,并且j的dp值大于当前的m,那么更新当前的m 11 { 12 m = dp[j]; 13 } 14 } 15 dp[i] = m + 1; //循环结束的时候累加m 16 } 17 m = 0; 18 for(i = 1; i <= n; i++) 19 { 20 if(dp[i] > m) 21 m = dp[i]; 22 } 23 return m; 24 }
但是我自己去年写的代码确实贪心的做法,囧... 也贴出来晒晒吧...
View Code
1 /* * 2 *hdu 最少拦截系统 3 Time 2011.8.1 4 * */ 5 #include<iostream> 6 #include<cmath> 7 using namespace std; 8 int n, a[40040], u[40040]; 9 10 void deal() 11 { 12 int i, j, tmp, pos, cnt=0; 13 u[0]=1; 14 for(i=1; i<n; ++i) 15 { 16 pos=0; 17 for(j=i; j>=0; --j) 18 if(a[i]>a[j] && pos<u[j]) pos=u[j]; 19 u[i]=pos+1; 20 if(cnt<u[i]) cnt=u[i]; 21 } 22 cout<<cnt<<endl; 23 } 24 25 int main() 26 { 27 //freopen("t.in","r",stdin); 28 //freopen("t.out","w",stdout); 29 int i, j; 30 while(cin>>n) 31 { 32 memset(u,0,sizeof(u)); 33 for(i=0; i<n; ++i) 34 scanf("%d",&a[i]); 35 36 deal(); 37 } 38 return 0; 39 }

浙公网安备 33010602011771号