ZJUT1632 搭积木 ZJUT1278 最多拦截导弹数 LIS

Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1632

 

Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1278

 

其实两道题是同一个题,都是LIS类型。

 

刚开始是做1278,但是出来后过不了,便试了一下1632,结果过了。

 

网上找了下原始版的LIS代码,看不出个所以然。

 

找JL帮忙,他给了个数据,没过。

 

我一看,把等号去掉,轻松就AC了。

 

结论就是,有些OJ的CASE很水= =(后来发现其实不是CASE水,而是我水……题意确实有点不同……)

 

经典的LIS自己可以去找下看看,代码如下:

 

#include<iostream>
using namespace std;

int a[1005];
int dp[1005];
int main()
{
    int n,i,j,ans,max;
    while(cin>>n&&n)
    {  
        for(i=1;i<=n;i++)
   cin>>a[i];
        max=0;
        for(i=1;i<=n;i++)
        {
   dp[i]=1;
   for(j=1;j<=i-1;j++)  
   {
    if(a[j]>=a[i]&&dp[i]<=dp[j]+1)
     dp[i]=dp[j]+1;
   }
   if(dp[i]>max) max=dp[i];  
        }
  
        cout<<max<<endl;
    }
 return 0;
}

 

我其实是之前看过了别人文章的介绍所以用了另一种方法。

 

他的那种是新建一个数组然后记录序列长度数,而我的是直接在原来的数据数组里操作。

 

初始序列长度为0。

 

对于每一个数都跟序列长度以内的数比较,如果刚好比某一个数大,则把它覆盖到上面去。

 

如果超出序列长度还没找到比他小的数,则把这个数添加到序列的尾部并使长度加一。

 

这个算法对比上一个可以节省很多对比的次数。

 

所以结果出来后是453MS和31MS的差距。

 

赞一下自己~也赞一下JL~。

 

以下贴代码:

 

#include <iostream>
using namespace std;
int main()
{
 int ct[1005],num;
 int n,i,x,j;
 while(scanf("%d", &n)!=EOF)
 {
  if (n==0) break;
  num = 0;
  for (i=0; i<n; i++)
  {
   scanf("%d", &ct[i]);
  }
  for (i=0; i<n; i++)
  {
   x = ct[i];
   for (j=0; j<num; j++)
   {
    if (x>=ct[j])//这里如果使用>=则为严格单调递减,否则为单调非递增
    {
     ct[j] = x;
     break;
    }
   }
   if (j==num)
   {
    ct[num] = x;
    num++;
   }
  }
  printf("%d/n", num);
 }
 return 0;
}

 

今天开始学习DP,不过乱找的几道题都看不出个所以然。哎~

 

继续努力啦!!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值