zoukankan      html  css  js  c++  java
  • Codeforces 766C:Mahmoud and a Message(DP)

    题目链接:http://codeforces.com/problemset/problem/766/C

     题意

    有一个长度为n的字符串,第二行有26个数字,位置1~26对应为a~z的字母,数值表示该字母不能出现在长度超过该值的子串中。

    • 求有多少种划分该字符串的方法
    • 求该字符串划分成子串后最大的子串的长度
    • 求该字符串划分成满足要求的子串需要至少划分多少次

    AC代码

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <limits.h>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <set>
    #include <string>
    #define ll long long
    #define ms(a) memset(a,0,sizeof(a))
    #define pi acos(-1.0)
    #define INF 0x3f3f3f3f
    const double E=exp(1);
    const int maxn=1e6+10;
    const int mod=1e9+7;
    using namespace std;
    char ch[maxn];
    int c[maxn];
    int a[maxn];
    int dp[4][maxn];
    int main(int argc, char const *argv[])
    {
    	ios::sync_with_stdio(false);
    	int n;
    	cin>>n;
    	cin>>ch;
    	for(int i=0;i<26;i++)
    		cin>>a[i];
    	for(int i=0;i<n;i++)
    	{
    		c[i]=ch[i]-'a';
    	}
    	dp[0][0]=1;//从位置0开始转移
    	for(int i=1;i<=n;i++)
    	{
    		int res=INT_MAX/2;
    		dp[1][i]=INT_MIN/2;
    		dp[2][i]=INT_MAX/2;
    		for(int j=i-1;j>=0;j--)
    		{
    			res=min(res,a[c[j]]);
    			if(res<i-j)
    				break;
    			dp[0][i]=(dp[0][i]%mod+dp[0][j]%mod)%mod;
    			dp[1][i]=max(dp[1][i],max(dp[1][j],i-j));
    			dp[2][i]=min(dp[2][i],dp[2][j]+1);
    		}
    	}
    	for(int i=0;i<3;i++)
    		cout<<dp[i][n]<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Python-24-多线程
    RT-Thread动态内存堆的使用
    Linux编程概念
    Linux_C语言基础
    文件IO_open(),read(),write(),lseek(),close()
    SourceTree跳转注册的方法
    Linux——软件安装
    初学DOM树解析xml文件
    简单json语句转化为map保存
    最大独立集求解
  • 原文地址:https://www.cnblogs.com/Friends-A/p/10324389.html
Copyright © 2011-2022 走看看