HDU1160FatMouse's Speed

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<set>
  5 #include<stack>
  6 using namespace std;
  7 const int maxn=1010;
  8 struct point
  9 {
 10     int w,s,per,id;
 11 }p[maxn];
 12 int cmp(point a,point b)
 13 {
 14     return a.s>b.s;
 15 }
 16 int dp[maxn];
 17 int main()
 18 {
 19     int i,j,k,n,m;
 20     n=1;
 21     memset(dp,0,sizeof(dp));
 22     while(scanf("%d%d",&p[n].w,&p[n].s)!=EOF)
 23     {
 24         p[n].id=n;
 25         p[n].per=0;
 26         n++;
 27      }
 28      sort(p+1,p+n,cmp);
 29      int max;
 30      dp[1]=1;//dp[i]记录以第i个元素结尾的最长递增的长度
 31      for(i=2;i<n;i++)
 32      {
 33          max=0;
 34          for(j=1;j<i;j++)
 35          {
 36              if(p[j].w<p[i].w && p[j].s>p[i].s)
 37              {
 38                  if(dp[j]>=max)
 39                  {
 40                      max=dp[j];
 41                      p[i].per=j;//记录i位置的前驱
 42                  }
 43              }
 44              dp[i]=max+1;
 45          }
 46      }
 47      max=-0x3f3f3f3f;
 48      int end;
 49     for(i=1;i<n;i++)
 50     {
 51         if(max<=dp[i])
 52         {
 53             max=dp[i];
 54             end=i;
 55         }
 56     }
 57      printf("%d\n",max);
 58      stack<int> ok;
 59      while(end!=0)
 60      {
 61          ok.push(end);
 62          end=p[end].per;
 63      }
 64      while(!ok.empty())
 65      {
 66          printf("%d\n",p[ok.top()].id);
 67          ok.pop();
 68      }
 69      return 0;
 70 }
 71 
 72 
 73 /*二分写法*/
 74 #include<iostream>
 75 #include<cstring>
 76 #include<cstdio>
 77 #include<algorithm>
 78 using namespace std;
 79 struct X{
 80     int s,w,sb;
 81 };
 82 bool cmp(X a,X b)
 83 {
 84     return (a.s>b.s)||(a.s==b.s&&a.w>b.w);//这里排序注意了,由于本题数据水的不能再水,a.w<b.w也过了,正解应该是a.w>b.w
 85 }
 86 X xx[1005];
 87 int pre[1005];
 88 int fnm[1005];
 89 int shuchu[1005];
 90 int main()
 91 {
 92     int i=0,n=1,w,s;
 93     while(scanf("%d%d",&w,&s)!=EOF)
 94     {
 95         xx[n].w=w;
 96         xx[n].s=s;
 97         xx[n].sb=n++;
 98     }
 99     n--;
100     sort(xx+1,xx+n+1,cmp);/*
101     for(i=1;i<=n;i++)
102         printf("%d %d\n",xx[i].w,xx[i].s);*/
103     int lsb=0,j,l,r;
104     fnm[0]=1;
105     pre[fnm[0]]=-1;
106     for(i=2;i<=n;i++)
107     {
108         l=0,r=lsb;
109         while (l<=r) //二分查找
110         {
111             int mid = (l+r)>>1;
112             if (xx[fnm[mid]].w < xx[i].w)
113                 l=mid+1;
114             else
115                 r=mid-1;
116         }
117         j=l;
118         if(j>lsb)
119             lsb++;
120         fnm[j]=i;//存下标,相当于c[j]=a[i];
121         if(j!=0)//fnm小标从0开始,所以要判断第一个
122             pre[i]=fnm[j-1];//j-1的元素肯定是最长递增中的元素
123         else
124             pre[i]=-1;
125     }
126     printf("%d\n",lsb+1);
127     int xsb=fnm[lsb];
128     i=0;
129     while(pre[xsb]!=-1)
130     {
131         shuchu[i++]=xx[xsb].sb;
132         xsb=pre[xsb];
133     }
134     printf("%d\n",xx[xsb].sb);
135     for(i=lsb-1;i>=0;i--)
136         printf("%d\n",shuchu[i]);
137     return 0;
138 }

 

posted on 2013-08-19 01:54  ok_boy  阅读(256)  评论(0编辑  收藏  举报

导航