【HDU6017】Girls Love 233 (DP)

题目大意:一个由2和3组成的长度为n的串,有m/2次机会操作(将相邻两个数交换),问最多可以得到多少个233?

题解&代码:

/*
dp[i][j][k]表示第i个2放在第j位,用了k次操作的233最多个数。
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define MAXN 105
int dp[MAXN][MAXN][MAXN];
int pos[MAXN];
int main()
{
    int T,n,m,i,j,k,l,x,ans,ct,mov;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        m/=2;
        ct=0;
        memset(dp,-1,sizeof dp);
        for(i=1;i<=n;i++)
        {
            scanf("%1d",&x);
            if(x==2)
                pos[++ct]=i;
        }
        dp[0][0][0]=0;
        for(i=1;i<=ct;i++)//i从1枚举到2的个数
            for(j=i,mov=abs(pos[i]-j);j<=n-ct+i;j++,mov=abs(pos[i]-j))//j至少放在第i位(把i个2挤在前面),最多放在n-ct+i位(把i个2挤在最后面),mov第i个2需要移动步数。
                for(k=mov;k<=m;k++)//操作次数
                {
                    for(l=i-1;l<=j-1;l++)
                        if(~dp[i-1][l][k-mov])//上一状态可行
                            dp[i][j][k]=max(dp[i][j][k],dp[i-1][l][k-mov]+(j-l>2&&l!=0));//加上是否新产生233
                }
        ans=0;
        if(ct!=0)
            for(j=ct,mov=abs(pos[ct]-j);j<=n;j++,mov=abs(pos[ct]-j))
                for(k=mov;k<=m;k++)//枚举最后一个2的状态
                    ans=max(ans,dp[ct][j][k]+(j<=n-2));//加上最后一个2是否产生233
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值