hdu6549(dp)

#include<bits/stdc++.h>
using namespace std ;
const int N = 2e5+23 ;
//思路:dp
//dp[i][j][k]为处理了1->i。第i个位置为j+'a',最多k段的最小处理数 
//1.s[i]==j+'a' 第i位不用修改,则由i-1转移过来,dp[i][j][k] = dp[i-1][j][k]
//2.s[i]!=j+'a' 第i位用修改,贪心,由p=i-l转移,dp[i][j][k]=min(dp[p][j][k],dp[p][c][k-1])+1
//解决:dp[i][c][k]: dp[i][26][k]=min(dp[i][c][k])

//core:1.线性处理,无后效性 ,所以无需dp[i][j][k]=min(dp[i][j][k],...) 
//2.总共26个字母,所以dp[位置i][字母][段落]:1-i处理完
//转移过程:第i位要不要修改 
//贪心:更改越多越好 
int n,l,op ;
char s[N] ;
int dp[N][28][11] ;
void solve()
{
    memset(dp,0x3f,sizeof(dp)) ;
    for(int j = 0 ; j < 26 ; j++)
    {
        if(s[1]==j+'a') dp[1][j][1] = 0 ;
        else dp[1][j][1] = 1 ;
     } 
    dp[1][26][1] = 0 ;
    for(int i = 2 ; i <= n ; i++)
    {
        for(int j = 0 ; j < 26 ; j++)
        {
            for(int k = 1 ; k <= op ; k++)
            {
                if(s[i]==j+'a') dp[i][j][k] = dp[i-1][j][k] ;
                else 
                {
                    int p = max(1,i-l) ;
                    dp[i][j][k]=min(dp[p][j][k],dp[p][26][k-1])+1 ;
                }
                dp[i][26][k] = min(dp[i][26][k],dp[i][j][k]) ;
                //printf("dp[%d][%d][%d]=%d\n",i,j,k,dp[i][j][k]) ;
            }
        }
    }
    printf("%d\n",dp[n][26][op]) ;
 } 
int main()
{
    scanf("%d%d%d",&n,&l,&op) ;
    scanf("%s",s+1) ;
    solve() ;
    return 0 ;
}

参考:

2019CCPC女生赛_bjfu170203101的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值