zoukankan      html  css  js  c++  java
  • ZOJ 1025 Wooden Sticks (DP)

    题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1025

    如果我们定义在一个sticks序列中,对所有的 j>i 均满足 :  sticks[i].l>=sticks[j].l 且 sticks[i].w>=sticks[j].w  ,则称这个序列为一个 “簇”。本题就是求把所有的元素分为最少的簇数。

    假设输入为A,首先把A排序(按 l 的增序,若两个元素的 l 相同,则按 w 的增序),排序后的序列称为B,对序列B按照元素的属性 w 求最长递减子序列的长度(严格递减),记为len。则我们要求得最少簇数就等于 len 。

    最长递减子序列的动态规划方法详见我的另一篇博客:http://www.cnblogs.com/TenosDoIt/archive/2013/04/19/3031589.html

    下面我们证明最少簇数 cu 等于 len:

    将最长递减子序列记为C,则C中的元素满足C[i].l>=C[j].l && C[i].w<C[j].w ( 其中 i<j ),他们不满足簇的性质。因此最长递减子序列中的len个元素必定每个都分布在不同的簇中,因此最少的簇数为len。

    代码如下:

     1 #include<iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 struct node
     7 {
     8     int l;
     9     int w;
    10 };
    11 
    12 bool comp(struct node a,struct node b)
    13 {
    14     if(a.l==b.l)
    15         return a.w<b.w;
    16     else return a.l<b.l;
    17 }
    18 
    19 
    20 int main()
    21 {
    22     int caseNum;
    23     cin>>caseNum;
    24     while(caseNum--)
    25     {
    26         int N;
    27         vector<node> sticks;
    28         cin>>N;
    29         for(int i=1;i<=N;++i)
    30         {
    31             node tmp;
    32             cin>>tmp.l>>tmp.w;
    33             sticks.push_back(tmp);
    34         }
    35         sort(sticks.begin(),sticks.end(),comp);
    36 
    37         int *F=new int[N+1];
    38         int result=0;
    39         F[0]=1;
    40         for(int i=1;i<N;i++)
    41         {
    42             F[i]=1;
    43             for(int j=0;j<i;j++)
    44             {
    45                 if(sticks[i].w<sticks[j].w)
    46                     F[i]=max(F[i],F[j]+1);
    47             }
    48             
    49             if(F[i]>result)
    50                 result=F[i];  
    51         }
    52         delete []F;
    53         cout<<result<<endl;
    54     }
    55     return 0;
    56 }

     【版权声明】转载请注明出处 http://www.cnblogs.com/TenosDoIt/archive/2013/04/19/3031727.html

  • 相关阅读:
    计数和查找
    遍历
    top小火箭
    leetcode 字符串中的第一个唯一字符
    leetcode 颠倒整数
    leetcode 反转字符串
    leetcode 有效的数独
    leetcode 两数之和
    leetcode 移动零
    leetcode 加一
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3031727.html
Copyright © 2011-2022 走看看