统计特殊子序列数目(0,1,2)DP

今天参加Nordic Collegiate Programming Contest 2020,发现这个G题和上周力扣的周赛的第三道题一模一样,我都怀疑农大的参加完周赛直接改的这个题。不过由于英语问题,我读错题了,我第一次知道了must have 是一定是的意思,这个单词如果按照必须有这个意思跟周赛的题一模一样,可惜大意失荆州。
先上力扣周赛题
题目链接
特殊序列 是由 正整数 个 0 ,紧接着 正整数 个 1 ,最后 正整数 个 2 组成的序列。

比方说,[0,1,2] 和 [0,0,1,1,1,2] 是特殊序列。
相反,[2,1,0] ,[1] 和 [0,1,2,0] 就不是特殊序列。
给你一个数组 nums (仅 包含整数 0,1 和 2),请你返回 不同特殊子序列的数目 。由于答案可能很大,请你将它对 109 + 7 取余 后返回。

一个数组的 子序列 是从原数组中删除零个或者若干个元素后,剩下元素不改变顺序得到的序列。如果两个子序列的 下标集合 不同,那么这两个子序列是 不同的 。

示例 1:

输入:nums = [0,1,2,2]
输出:3
解释:特殊子序列为 [0,1,2,2],[0,1,2,2] 和 [0,1,2,2] 。

1 <= nums.length <= 105
0 <= nums[i] <= 2

class Solution {
private:
    static constexpr int mod = 1000000007;

public:
    int countSpecialSubsequences(vector<int>& nums) {
        int f0 = 0, f1 = 0, f2 = 0;
        for (int num: nums) {
            if (num == 0) {
                f0 = (f0 * 2 + 1) % mod;
            }
            else if (num == 1) {
                f1 = (f1 * 2 % mod + f0) % mod;
            }
            else {
                f2 = (f2 * 2 % mod + f1) % mod;
            }
        }
        return f2;
    }
};

简单的DP,虽然当时周赛我没做出来,但是我补过了,最近没咋做DP题,基础课还没学到就好了。

这里得把题粘上must have = 一定是,意思是除了第一首歌和最后一首歌全是评级为二的歌。。。。。。。。。。。。。。。。。。。。。。😶无语

题目链接在此

Your friend Tóti is an aspiring musician. He has written nn songs, each of which has a hype rating of either 11, 22, or 33.A higher hype rating means the song has more energy. Tóti is planning his first live performance and needs your help. He wants to know how many setlists he can make. A setlist consist of at least three songs, the first song must have hype rating 11, the last song must have hype rating 33, and all other songs must have hype rating 22. Tóti also wants to play the songs in the same order he wrote them.

Given the hype rating of each of Tóti’s songs in the order he wrote them, how many setlists can he make?

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define L long long
const L mod(1e9+7);
int n;
L f1,f2,f3;
int main(){
	scanf("%d",&n);
	for(int i=1,x;i<=n;++i){
		scanf("%d",&x);
		if(x==1){
			f1=(f1+1)%mod;
		}
		
		if(x==2){
			f2=(f2*2%mod+f1)%mod;
		}
		if(x==3){
			f3=(f3+f2)%mod;
		}
	
	}
	printf("%lld\n",f3);
}

麻了!!!
再来一道变形例题,可倒着分析
题目链接++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值