【dp】小白月赛21-I love you

引言:
为什么我要看了别人的代码才会题,呜呜呜。好了,这道题我觉得很有必要记录一下,我觉得这些大佬的想法太厉害了,所以我就把它借鉴过来了。
题目:
I love you
链接:https://ac.nowcoder.com/acm/contest/3947/I
来源:牛客网

题目描述
此时相望不相闻,愿逐月华流照君。
一纸情书,到底蕴含了多少倍的爱情呢?
I love you, not only for what you are, but for what I am when I am with you.

输入描述:
共一行:一封若干个字符的情书(大小写不敏感)。
情书不会超过684594个字符(大写、小写字母)。
输出描述:
共一行:包含一个整数,即iloveyou在情书中作为子序列出现的次数。
由于答案可能很大,请输出对20010905取模后的值。

示例1
输入
复制
IloveyouNotonlyforwhatyouareButforwhatIamWhenIamwithyouIloveyouNotonlyforwhatYouhavemadeofyourselfButforwhatYouaremakingofme
输出
复制
2864
解法:
以我的脑回路咋可能想到dp,我就只会暴力暴力再暴力,然后这道题暴力我都不知道咋暴力。大佬的做法是这样的,I love you一共八个字母构成一个字符串,由于不区分大小写,我们用tolower(这可是c语言里面提供的函数哦,是不是忘了呢)转成小写来考虑。对于dp[i]表示的是前i个字母构成的前缀的总个数,那么dp[8]就是我们的答案了。
实现:
关键来了,我们dp[1]每当遇到字母i就让他++,这完全没毛病,他自己就是一个前缀。对于dp[2]呢,这就不一样了,我们想一想是不是前面有多少个dp[1],我们就能构成多少个IL这样的前缀呢,也就是说dp[2]=dp[2]+dp[1]%mod。对于ILO也是一样的操作,依次类推罢了。不过,要注意的是我们有两个o,那遇到了怎么办呢,完全没关系,但是你要对两个有o的地方都进行更新。比如,现在我们遇到了一个o,那么对于dp[3],我们前面已经对dp[2]进行了更新,故它将会更新。而对于后面那个dp[7]的o,由于我们还没有对dp[6]进行更新,故它的值不会改变,直到我们在给定字符串中找到了前面的所有前缀,才会对他进行更新。所以下面的代码里面我们用的是if而没有用else if。
代码:

#include<bits/stdc++.h>
using namespace std;

const int mod=20010905;
int dp[10];
typedef long long ll;
void solve(){
	string s;
	cin>>s;
	for(int i=0;i<s.length();i++){
		char x=tolower(s[i]);
		if(x=='i'){
			dp[1]++;
		}
		if(x=='l'){
			dp[2]=(dp[2]+dp[1])%mod;
		}
		if(x=='o'){
			dp[3]=(dp[3]+dp[2])%mod;
		}
		if(x=='v'){
			dp[4]=(dp[4]+dp[3])%mod;
		}
		if(x=='e'){
			dp[5]=(dp[5]+dp[4])%mod;
		}
		if(x=='y'){
			dp[6]=(dp[6]+dp[5])%mod;
		}
		if(x=='o'){
			dp[7]=(dp[7]+dp[6])%mod;
		}
		if(x=='u'){
			dp[8]=(dp[8]+dp[7])%mod;
		}
	}
	cout<<dp[8]<<endl;
}

int main(){
	solve();
	return 0;
}

项目类代码写多了,不喜欢main函数里面一堆东西,还是这样舒服。

发布了59 篇原创文章 · 获赞 86 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tran_sient/article/details/104411438
今日推荐