hdu 4105 Electric wave DP

本文介绍了一种算法,用于在记录电波数据时插入空格,确保数据的有效性。算法通过比较相邻数据点来确定插入空格的最大数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description
  
  
Ali was doing a physic experiment which requires him to observe an electric wave. He needs the height of each peak value and valley value for further study (a peak value means the value is strictly larger than its neighbors and a valley value means the value is strictly smaller than its neighbors). He did write these numbers down but he was too careless that he wrote them in a line without separations, such as “712495” may represent “7 12 4 9 5”. The only information he can remember was: 1. The data begins with a valley value 2. Each value is either a peak value or a valley value Now he wants to insert blanks to make the data valid. If multiple solutions exist, he will choose the one with more blanks.
 

Input
  
  
The input consists several testcases. The first line contains one integer N (1 <= N <= 100), the length of the data. The second line contains one string S, the data he recorded. S contains only digits.
 

Output
  
  
Print one integer, the maximum number of blanks he can insert.
 

Sample Input
  
  
6 712495
 

Sample Output
  
  
4
Hint
The separated data may have leading zeros.

//


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
int n;
int a[110];
int f[110][2][110];
int compare(int l1,int r1,int l2,int r2)
{//cout<<l1<<".."<<r1<<".."<<l2<<".."<<r2<<endl;
    while(a[l1]==0&&l1<=r1) l1++;
    while(a[l2]==0&&l2<=r2) l2++;
    int len1=r1-l1+1;
    int len2=r2-l2+1;
    if(len1>len2) return 1;
    else if(len1<len2) return -1;
    for(int k=0;k<len1;k++)
    {
        if(a[l1+k]>a[l2+k]) return 1;
        else if(a[l1+k]<a[l2+k]) return -1;
    }
    return 0;
}
int main()
{
    while(scanf("%d",&n)==1)
    {
        char str[110];scanf("%s",str);
        for(int i=1;i<=n;i++) a[i]=str[i-1]-'0';
        memset(f,-1,sizeof(f));
        f[1][0][1]=0;
        for(int i=2;i<=n;i++)
        {
            f[i][0][i]=0;
            for(int j=1;j<i;j++)
            {
                for(int l=1;l<=i-j;l++)
                {//cout<<compare(i-j+1,i,i-j-l+1,i-j)<<"........"<<endl;
                    if(compare(i-j+1,i,i-j-l+1,i-j)<0)
                    {
                        if(f[i-j][1][l]==-1) continue;
                        f[i][0][j]=max(f[i][0][j],f[i-j][1][l]+1);
                    }
                    if(compare(i-j+1,i,i-j-l+1,i-j)>0)
                    {
                        if(f[i-j][0][l]==-1) continue;
                        f[i][1][j]=max(f[i][1][j],f[i-j][0][l]+1);
                    }
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {//cout<<f[n][0][i]<<"..."<<f[n][1][i]<<endl;
            ans=max(ans,f[n][0][i]);
            ans=max(ans,f[n][1][i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*


f[i][2][j]表示前i个数以j个数结尾(0:低谷,1:高地)的插入最多空格数目




f[i][0][j]=max(f[i-k][1][l])+1;
f[i][1][j]=max(f[j-k][0][l])+1;




3
101
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值