题目链接:http://acm.fzu.edu.cn/problem.php?pid=2218
题意:给出字符串,只包含m个字母。求两个子串,相互间不包含相同字母的长度的乘积最大
思路:首先求出每个状态所能达到的最大长度,再求出小于等于这种状态字母数的最大长度,最后求最大乘积。
代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
char c[2005];
int dp[1<<17];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
cin>>c;
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
int temp=0;
for(int j=i;j<n;j++)
{
temp=temp|(1<<(c[j]-'a'));//所包含的字母
dp[temp]=max(dp[temp],j-i+1);//只包含这个字串的几个字母所能达到的最大长度
}
}
for(int i=0;i<(1<<m);i++)
{
for(int j=0;j<m;j++)
{
if(i&(1<<j))
{
int z=i-(1<<j);//减去这个字母后的状态
dp[i]=max(dp[i],dp[z]);
}
}
}
int ans=0;
for(int i=0;i<(1<<m);i++)
{
ans=max(ans,dp[i]*dp[((1<<m)-1)-i]);
}
printf("%d\n",ans);
}
return 0;
}