HDU1160FatMouse's Speed
来源:互联网 发布:linux home没root权限 编辑:程序博客网 时间:2024/05/19 22:58
#include<stdio.h>#include<string.h>#include<algorithm>#include<set>#include<stack>using namespace std;const int maxn=1010;struct point{ int w,s,per,id;}p[maxn];int cmp(point a,point b){ return a.s>b.s;}int dp[maxn];int main(){ int i,j,k,n,m; n=1; memset(dp,0,sizeof(dp)); while(scanf("%d%d",&p[n].w,&p[n].s)!=EOF) { p[n].id=n; p[n].per=0; n++; } sort(p+1,p+n,cmp); int max; dp[1]=1;//dp[i]记录以第i个元素结尾的最长递增的长度 for(i=2;i<n;i++) { max=0; for(j=1;j<i;j++) { if(p[j].w<p[i].w && p[j].s>p[i].s) { if(dp[j]>=max) { max=dp[j]; p[i].per=j;//记录i位置的前驱 } } dp[i]=max+1; } } max=-0x3f3f3f3f; int end; for(i=1;i<n;i++) { if(max<=dp[i]) { max=dp[i]; end=i; } } printf("%d\n",max); stack<int> ok; while(end!=0) { ok.push(end); end=p[end].per; } while(!ok.empty()) { printf("%d\n",p[ok.top()].id); ok.pop(); } return 0;}/*二分写法*/#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;struct X{ int s,w,sb;};bool cmp(X a,X b){ return (a.s>b.s)||(a.s==b.s&&a.w>b.w);//这里排序注意了,由于本题数据水的不能再水,a.w<b.w也过了,正解应该是a.w>b.w}X xx[1005];int pre[1005];int fnm[1005];int shuchu[1005];int main() { int i=0,n=1,w,s; while(scanf("%d%d",&w,&s)!=EOF) { xx[n].w=w; xx[n].s=s; xx[n].sb=n++; } n--; sort(xx+1,xx+n+1,cmp);/* for(i=1;i<=n;i++) printf("%d %d\n",xx[i].w,xx[i].s);*/ int lsb=0,j,l,r; fnm[0]=1; pre[fnm[0]]=-1; for(i=2;i<=n;i++) { l=0,r=lsb; while (l<=r) //二分查找 { int mid = (l+r)>>1; if (xx[fnm[mid]].w < xx[i].w) l=mid+1; else r=mid-1; } j=l; if(j>lsb) lsb++; fnm[j]=i;//存下标,相当于c[j]=a[i]; if(j!=0)//fnm小标从0开始,所以要判断第一个 pre[i]=fnm[j-1];//j-1的元素肯定是最长递增中的元素 else pre[i]=-1; } printf("%d\n",lsb+1); int xsb=fnm[lsb]; i=0; while(pre[xsb]!=-1) { shuchu[i++]=xx[xsb].sb; xsb=pre[xsb]; } printf("%d\n",xx[xsb].sb); for(i=lsb-1;i>=0;i--) printf("%d\n",shuchu[i]); return 0; }