HDOJ 4749 - Parade Show 思维...贪心...

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kk303/article/details/11880643

              题意:

                      现在给出了一列数..再给出了一列参照数列..参照数列的意思是其每个数代表一个高度..而大小关系同样也满足..现在问可以将所给的一列数分割成多少个和满足参照数列的数列...

              题解:

                      注意的是参照数列的每个数只为(1~25)....所以可以用25个vector记录当前参照数列那个数在哪些位置出现过..那么在枚举起点进行判断时..先判断所有应该相同的数是否相同..再比较大小关系是否满足...

                      值得注意的是本题是满足贪心的..比如从1开始可以匹配过去..从2开始也可以..那么选择从1开始的会给后面的留出更多的选择。这个意思就是从第一个数开始枚举起点..当找到了一个后..枚举起点的指针立马就跳到匹配完的后面一个位置继续匹配...


Program:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdlib>
#include<stack>
#include<map>
#define MAXN 100005
#define MAXM 1000505
#define ll long long 
#define eps 1e-10
using namespace std;  
int a[MAXN],d[30];
vector<int> T[30];
bool ok(int t,int m,int k)
{
    int i,p;
    memset(d,0,sizeof(d));
    for (p=1;p<=k;p++)
       for (i=0;i<T[p].size();i++)
       {
               if (!i) d[p]=a[t+T[p][i]];
               else
               if (a[t+T[p][i]]!=d[p]) return false;
       }
    for (i=1;i<k;i++)
       if (d[i] && d[i+1])
          if (d[i]>=d[i+1]) return false;
    return true;
}
int main()
{ 
    int n,m,k,x,i,t,num; 
    while(~scanf("%d%d%d",&n,&m,&k))
    {  
             for (i=1;i<=n;i++) scanf("%d",&a[i]);
             for (i=1;i<=k;i++) T[i].clear();
             for (i=0;i<m;i++) scanf("%d",&x),T[x].push_back(i);    
             num=0;
             for (t=1;t<=n-m+1;t++)
                 if (ok(t,m,k)) t+=m-1,num++;
             printf("%d\n",num);             
    }
    return 0;
}


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页