计蒜客Concerts

题目链接

题意:有n天,每天都会有一只乐队的演唱会,一只乐队可多天进行演唱会,乐队编号为A~Z,按乐队编号给出john观看乐队演唱会的序列,每看完某乐队的演唱会都将休息相应天数

john将按序列逐个观看演唱会,那么john在这n天中的出勤情况有多少种?

解法:动态规划,从后往前推,f[i][j]表示第i+1天到第n天中看了k-j场演唱会的出勤情况种树;

得状态转移方程:f[i][j]+=f[i+1][j]+f[i+1+h[ap[i]-'A']][j+1],应需要取模以及判断边界因此代码写法将发生相应变化

即前i+2~n天看了k-j场的情况与第i+1天看了某乐队演唱会后休息相应天数后剩余的天数中看了k-j-1场的情况之和

题目所给数据范围有误;正确范围:n<=100000,k<=300

#include<iostream>
using namespace std;
#define p 1000000007
int h[30],n,k,f[100005][305];
string sx,ap;
int main(){
    cin>>k>>n;
    for(int i=0;i<26;i++) cin>>h[i];
    cin>>sx>>ap;
    for(int i=0;i<n;i++) if(sx[k-1]==ap[i]) f[i][k-1]=1;
    for(int i=n-1;i>=0;i--)
        for(int j=k-1;j>=0;j--){
            f[i][j]+=f[i+1][j];
            if(ap[i]==sx[j]&&i+1+h[ap[i]-'A'<n)
                f[i][j]=(f[i][j]+f[i+1+h[ap[i]-'A']][j+1])%p;
        }
    cout<<f[0][0]<<endl;
    return 0;
}

  

 

posted @ 2019-08-19 10:22  Evolutw  阅读(121)  评论(0)    收藏  举报