1、http://acm.hdu.edu.cn/showproblem.php?pid=1025
题目好难懂,懂了之后也没想到这是一个LIS的题目,注意输出的细节,wrong了n遍
输出,注意一条多条的不同输出,样例之间打印空行
2、题目大意
有2n个城市,其中有n个富有的城市,n个贫穷的城市,其中富有的城市只在一种资源富有,且富有的城市之间富有的资源都不相同,贫穷的城市只有一种资源贫穷,且各不相同,现在给出一部分贫穷城市的需求,每个需求都是一个贫穷的向一个富有的城市要资源,且每个富有的城市都想向贫穷的城市输入自己富有的那部分资源,现在为了运输要建设多条路,但是路与路之间不允许有交叉,求满足贫穷城市的各种要求最多可以建设多少条路
3、解题思路:
将贫穷的城市按从小到大的顺序排列,然后求富有的城市序号的最大上升子序列LIS解决即可
4、题目:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10612 Accepted Submission(s): 3024
2 1 2 2 1 3 1 2 2 3 3 1
Case 1: My king, at most 1 road can be built. Case 2: My king, at most 2 roads can be built.HintHuge input, scanf is recommended.
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 500005 int n; int stack[N]; struct node { int p; int r; }a[N]; int dp[N]; int cmp(node b,node c) { return b.p<c.p; } void LIS() { //dp[i]表示前i个数字中加上第i个数字后,有几个数字是递增的,即前i个数字中有多少个比第i个数字小的+1 //int stack[N]; memset(stack,0,sizeof(stack)); int top=0; stack[top]=-99999999; for(int i=1; i<=n; i++) { //如果a[i]>栈顶部元素,则压栈 if(a[i].r>stack[top]) { stack[++top]=a[i].r; dp[i]=top; } //如果a[i]不大于栈顶部元素,则二分查找第一个比a[i]大的元素 else { int l=1,r=top; while(l<=r) { int mid=(l+r)>>1; if(a[i].r>stack[mid]) { l=mid+1; } else r=mid-1; } //替换a[i] stack[l]=a[i].r; dp[i]=l; } } } int main() { int cas=0; while(scanf("%d",&n)!=EOF) { cas++; memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].p,&a[i].r); } sort(a+1,a+n+1,cmp); LIS(); int maxx=-999999; for(int i=1;i<=n;i++) { if(dp[i]>maxx) maxx=dp[i]; } if(maxx==1) { printf("Case %d:\n",cas); printf("My king, at most %d road can be built.\n\n",maxx); } else { printf("Case %d:\n",cas); printf("My king, at most %d roads can be built.\n\n",maxx); } } return 0; } /* 2 1 2 2 1 3 1 2 2 3 3 1 */
这样做也是对的,以下是ac代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 500005 int n; int stack[N]; struct node { int p; int r; }a[N]; int dp[N]; int cmp(node b,node c) { return b.p<c.p; } int maxx; void LIS() { memset(stack,0,sizeof(stack)); maxx=1; stack[1]=a[1].r; for(int i=2; i<=n; i++) { int l=1,r=maxx; while(l<=r) { int mid=(l+r)>>1; if(a[i].r>stack[mid]) { l=mid+1; } else r=mid-1; } stack[l]=a[i].r; if(l>maxx) maxx++; } } int main() { int cas=0; while(scanf("%d",&n)!=EOF) { cas++; memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].p,&a[i].r); } sort(a+1,a+n+1,cmp); LIS(); if(maxx==1) { printf("Case %d:\n",cas); printf("My king, at most 1 road can be built.\n\n"); } else{ printf("Case %d:\n",cas); printf("My king, at most %d roads can be built.\n\n",maxx); } } return 0; } /* 2 1 2 2 1 3 1 2 2 3 3 1 3 2 3 1 2 3 1 */