给你每个物体两个参数,求最长的链要求第一个参数递增,第二个参数递减,要求输出任意最长路径。

首先第一反应根据第二个参数排个序,然后不就是最长上升子序列的问题吗?

O(nlogn)的复杂度,当然这样可以写,写法也不难。

然后发现这个还是个DAG,也可以用拓扑排序来搞定,输出最长路径,复杂度O(n*n),更新的时候需要更新并记录每个点的前节点,最后倒序输出。

第二种就当练练手吧

先上第二种代码:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<map>
  5. #include<iostream>
  6. #include<vector>
  7. #include<cstring>
  8. #include<queue>
  9. using namespace std;
  10. int d;
  11. struct node
  12. {
  13. int x,y;
  14. }h[1005];
  15. vector<int> t[1005];
  16. int deg[1005];
  17. queue<int> q;
  18. int g[1005];
  19. int ans=0;
  20. int res=-1;
  21. int dp[1005];
  22. vector<int> s;
  23. void tp()
  24. {
  25. for(int i=0;i<d;i++)
  26. {
  27. if(deg[i]==0)
  28. {
  29. dp[i]=1;
  30. q.push(i);
  31. }
  32. }
  33. while(!q.empty())
  34. {
  35. int xx=q.front();
  36. if(dp[xx]>ans)
  37. {
  38. ans=dp[xx];
  39. res=xx;
  40. }
  41. q.pop();
  42. for(int i=0;i<t[xx].size();i++)
  43. {
  44. int w=t[xx][i];
  45. deg[w]--;
  46. if(dp[w]<dp[xx]+1)
  47. {
  48. dp[w]=dp[xx]+1;
  49. g[w]=xx;
  50. }
  51. if(deg[w]==0)
  52. q.push(w);
  53. }
  54. }
  55. }
  56.  
  57. int main()
  58. {
  59. //freopen("input.txt","r",stdin);
  60. int a,b;
  61. memset(g,-1,sizeof(g));
  62. while(scanf("%d%d",&a,&b)==2)
  63. {
  64. h[d].x=a;
  65. h[d].y=b;
  66. d++;
  67. }
  68. for(int i=0;i<d;i++)
  69. for(int j=0;j<d;j++)
  70. {
  71. if(h[i].x<h[j].x&&h[i].y>h[j].y){
  72. t[i].push_back(j);
  73. deg[j]++;
  74. }
  75. }
  76. tp();
  77. printf("%d\n",ans);
  78. s.push_back(res+1);
  79. while(g[res]!=-1)
  80. {
  81. s.push_back(g[res]+1);
  82. res=g[res];
  83. }
  84. int len=s.size();
  85. for(int i=len-1;i>=0;i--)
  86. printf("%d\n",s[i]);
  87. }

第一种代码稍后补上:

参考http://blog.csdn.net/dangwenliang/article/details/5728363

原理:O(N*N)的,一维,设dp[i]为以第i位为结尾的最长长度,dp[i]=max(dp[j])+1(j<i),然后记录前缀,输出路径。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<map>
  5. #include<iostream>
  6. #include<vector>
  7. #include<cstring>
  8. #include<queue>
  9. using namespace std;
  10. int d;
  11. struct node
  12. {
  13. int x,y,r;
  14. }h[1005];
  15. int hh[1005];
  16. int g[1005];
  17. vector<int> t;
  18. bool cmp(node a,node b)
  19. {
  20. if(a.y>b.y)
  21. return 1;
  22. return 0;
  23. }
  24. int f[1005];
  25. int ans,res;
  26. int main()
  27. {
  28. //freopen("input.txt","r",stdin);
  29. int a,b;
  30. memset(g,-1,sizeof(g));
  31. while(scanf("%d%d",&a,&b)==2)
  32. {
  33. h[d].x=a;
  34. h[d].y=b;
  35. h[d].r=d;
  36. d++;
  37. }
  38. sort(h,h+d,cmp);
  39. hh[0]=1;
  40. int res=-1;
  41. ans=0;
  42. for(int i=1;i<d;i++)
  43. {
  44. hh[i]=1;
  45. for(int j=0;j<i;j++)
  46. {
  47. if(h[i].x>h[j].x&&hh[i]<hh[j]+1)
  48. {
  49. hh[i]=hh[j]+1;
  50. g[i]=j;
  51. if(hh[i]>res)
  52. {
  53. ans=i;
  54. res=hh[i];
  55. }
  56. }
  57. }
  58. }
  59. printf("%d\n",res);
  60. t.push_back(ans);
  61. while(g[ans]!=-1)
  62. {
  63. t.push_back(g[ans]);
  64. ans=g[ans];
  65. }
  66. int len=t.size();
  67. for(int i=len-1;i>=0;i--)
  68. {
  69. printf("%d\n",h[t[i]].r+1);
  70. }
  71. }

然后来O(nlogn)算法。

首先能这么做,要满足dp的两个根本原则:1.无后效性,每一个点的状态都由其前面的点决定

                                                       2.每一步都是当前那一个整体最优。

    我们必须用到二分,但是这个前面的点的序列是不连续的,所以我们需要选出前面的点中每一步中的最优,来组成一个"标杆队列",因为对于数和数之间的前后关系是重要的,但对于当前的数,前面的数的前后关系是不重要的,如果每一次二分,dp的同时维护那个"标杆队列",我们可以保证那个队列是最优的,那么下一个点也会是最优的,也可以保证结果是最优的。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<map>
  5. #include<iostream>
  6. #include<vector>
  7. #include<cstring>
  8. #include<queue>
  9. using namespace std;
  10. int d=1;
  11. struct node
  12. {
  13. int x,y,r;
  14. }h[1005];
  15. int ans[1005];
  16. int hh[1005];
  17. int dp[1005];
  18. bool cmp(node a,node b)
  19. {
  20. if(a.y>b.y)
  21. return 1;
  22. else if(a.y==b.y&&a.x>b.x)
  23. return 1;
  24. return 0;
  25. }
  26.  
  27. int main()
  28. {
  29. //freopen("input.txt","r",stdin);
  30. int a,b;
  31. while(scanf("%d%d",&a,&b)==2)
  32. {
  33. h[d].x=a;
  34. h[d].y=b;
  35. h[d].r=d;
  36. d++;
  37. }
  38. sort(h+1,h+d,cmp);
  39. for(int i=1;i<d;i++)
  40. ans[i]=10005;
  41. int len=0;
  42. for(int i=1;i<d;i++)
  43. {
  44. int t=lower_bound(ans+1,ans+d,h[i].x)-ans;
  45. ans[t]=h[i].x;
  46. dp[i]=t;
  47. len=max(len,t);
  48. }
  49. printf("%d\n",len);
  50. int cc=len;
  51. int res=0;
  52. int f=10005;
  53. for(int i=d-1;i>0;i--)
  54. {
  55. if(len==0)
  56. break;
  57. if(dp[i]==len&&h[i].x<f)
  58. {
  59. hh[res++]=i;
  60. len--;
  61. f=h[i].x;
  62. }
  63. }
  64. for(int i=res-1;i>=0;i--)
  65. {
  66. printf("%d\n",h[hh[i]].r);
  67. }
  68. }

zoj1108 FatMouse's Speed的更多相关文章

  1. FatMouse's Speed——J

    J. FatMouse's Speed FatMouse believes that the fatter a mouse is, the faster it runs. To disprove th ...

  2. HDU 1160 FatMouse's Speed(要记录路径的二维LIS)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. HDU 1160 FatMouse's Speed (DP)

    FatMouse's Speed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Su ...

  4. FatMouse's Speed(HDU LIS)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. FatMouse's Speed 基础DP

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. zoj 1108 FatMouse's Speed 基础dp

    FatMouse's Speed Time Limit: 2 Seconds      Memory Limit:65536 KB     Special Judge FatMouse believe ...

  7. J - FatMouse's Speed

    p的思路不一定要到最后去找到ans:也可以设置成在中间找到ans:比如J - FatMouse's Speed 这个题,如果要是让dp[n]成为最终答案的话,即到了i,最差的情况也是dp[i-1],就 ...

  8. HDU 1160:FatMouse's Speed(LIS+记录路径)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. (最长上升子序列 并记录过程)FatMouse's Speed -- hdu -- 1160

    http://acm.hdu.edu.cn/showproblem.php?pid=1160 FatMouse's Speed Time Limit: 2000/1000 MS (Java/Other ...

随机推荐

  1. HTML 5 全局属性和事件属性

    1.HTML 5 全局属性 HTML 属性能够赋予元素含义和语境. 下面的全局属性可用于任何 HTML5 元素. NEW:HTML 5 中新的全局属性. 属性 描述 accesskey 规定访问元素的 ...

  2. c++中各种数据类型所占字节

    求各种数据类型所占用的字节数可调用sizeof函数,求各种数据类型的最大值可以调用limits标准库中的numeric_limits<T>::max(),numeric_limits< ...

  3. stuts1:(Struts)Action类及其相关类

    org.apache.struts.action.Action类是Struts的心脏,也是客户请求和业务操作间的桥梁.每个Action类通常设计为代替客户完成某种操作.一旦正确的Action实例确定, ...

  4. Problem 1008 Hay Points

    Problem Description Each employee of a bureaucracy has a job description - a few paragraphs that des ...

  5. Git学习04 --分支管理

    每次commit,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而是指向master ...

  6. Nginx学习笔记六Nginx的模块开发

    1.Nginx配置文件主要组成:main(全局配置)这部分的指令将影响其他所有部分.server(虚拟主机配置)这部分指令主要用于指定虚拟主机域名,IP和端口.upstream(主要为反向代理,负载均 ...

  7. 一种全新的MEMS开关——高性能、快速、低能耗以及双稳态

    这种开关最早由申军教授和研究生阮梅春发明,研究生埃里克·朗格卢瓦在简化结构和缩小尺寸上作了探索,黄志林用相同原理做出了MEMS光学镜子开关,曹志良改变设计.材料和工艺后制作出了能同步开关的矩阵.这种M ...

  8. 第3.3.4节 创建高级图形之RenderScript(二)

        Android视图框架对于创建复杂布局非常方便.然而,这种便利是以性能为代价的.当性能至关重要的时候,Android提供了几种更强大的图形处理能力,当然难度也是随之上升了.在本节中,我将介绍: ...

  9. Chapter 5. Label and Entry Widgets 标签和输入部件

    Chapter 5. Label and Entry Widgets  标签和输入部件 有时候,你需要用户输入特定的信息,比如他们的名字,地址或者 甚至序号. 简单的方式来实现这个是使用Enry 部件 ...

  10. pushMeBaby,github链接

    https://github.com/stefanhafeneger/PushMeBaby