题目连接:hdu 6103
题意:找出整个字符串中两个相同长度,但不重叠的连续字串,求满足他们的距离小于等于m的最长长度。
二分+dp应该也是能写的,但是我错了,应该是dp没写好, 队友写的dp过了。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 5005;
char str[20005];
short int dp[MAXN][MAXN];
bool judge(int n, int x, int len)
{
for(int i=0; i<=len-x-x; ++i)
{
for(int j=i+2*x-1; j<len; ++j)
{
if(i+x>j-x)
{
if(dp[i][j]<=n)
return true;
}
else
{
if(dp[i][j]-dp[i+x][j-x]<=n)
return true;
}
}
}
return false;
}
int main()
{
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d",&n);
scanf(" %s", str);
int len=strlen(str);
//memset(dp, 0, sizeof(dp));
int l, r;
for(int i=0; i<len; ++i)
{
l=i;
dp[i][i]=0;
r=i+1;
dp[l][r]=dp[l][r]+abs(str[l]-str[r]);
l--;
r++;
while(l>=0&&r<len)
{
dp[l][r]=dp[l+1][r-1]+abs(str[l]-str[r]);
l--, r++;
}
}
for(int i=0; i<len; ++i)
{
l=i-1;
r=i+1;
while(l>=0&&r<len)
{
dp[l][r]=dp[l+1][r-1]+abs(str[l]-str[r]);
l--, r++;
}
}
// for(int i=0; i<len; ++i)
// {
// for(int j=i; j<len; ++j)
// {
// printf("%d%c", dp[i][j], j==len-1?'\n':' ');
// }
// }
l=0, r=len;
while(l<r)
{
int mid=(l+r+1)>>1;
if(judge(n, mid, len))
l=mid;
else
r=mid-1;
}
printf("%d\n", l);
}
return 0;
}
以上是错误代码。
以下为AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 100011;
short dp[5005][5005];
char ch[5500];
int k;
int m;
bool panduan(int l)
{
int i,j;
for(i=1; i+2*l-1<=k; i++)
for(j=k; j-2*l+1>=i; j--)
{
if(dp[i][j]-dp[i+l][j-l]<=m)
return true;
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&m);
scanf("%s",ch+1);
k=strlen(ch+1);
int i,j;
for(i=1; i<k; i++)
dp[i][i]=0,dp[i][i+1]=abs(ch[i]-ch[i+1]);
for(i=3; i<=k; i++)
{
for(j=1; j+i-1<=k; j++)
dp[j][j+i-1]=dp[j+1][j+i-2]+abs(ch[j]-ch[j+i-1]);
}
int l=0,r=k/2;
int m;
while(l<r)
{
m=(l+r+1)>>1;
if(!panduan(m))
r=m-1;
else l=m;
}
printf("%d\n",l);
}
return 0;
}
看了网上写的, 感觉当时。。好傻
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 20005;
char str[MAXN];
int ans, len, m;
void solve(int x, int y)
{
int l=0, r=0, sum=0;
while(x-r>=0&&y+r<len)
{
if(sum+abs(str[x-r]-str[y+r])<=m)
{
sum+=abs(str[x-r]-str[y+r]);
r++;
ans=max(ans, r-l);
}
else
{
sum-=abs(str[y+l]-str[x-l]);
l++;
ans=max(ans,r-l);
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d", &m);
scanf("%s", str);
ans=0;
len = strlen(str);
for(int i=0; i<len; ++i)
{
solve(i, i+1);
solve(i-1,i+1);
}
printf("%d\n", ans);
}
return 0;
}