子 2023
【问题描述】
小蓝在黑板上连续写下从 1 到 2023 之间所有的整数,得到了一个数字序列:
S = 12345678910111213 . . . 20222023。
小蓝想知道 S 中有多少种子序列恰好等于 2023?
提示,以下是 3 种满足条件的子序列(用中括号标识出的数字是子序列包含的数字):
1[2]34567891[0]111[2]1[3]14151617181920212223…
1[2]34567891[0]111[2]131415161718192021222[3]…
1[2]34567891[0]111213141516171819[2]021222[3]…
注意以下是不满足条件的子序列,虽然包含了 2、0、2、3 四个数字,但是顺序不对:
1[2]345678910111[2]131415161718192[0]21222[3]…
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分
【思路】
这是一道简单的动规题,建立一个dp数组,dp[1]表示到目前为止‘2’出现的次数,dp[2]表示目前为止‘20’出现的次数,dp[3]表示目前为止‘202’出现的次数,dp[4]表示目前为止‘2023’出现的次数。
对于s串的第i个字符,如果是‘0’,那么此时的dp[2]的数量为前i-1个’20’出现的次数+前i-1个‘2’出现的次数(dp[2]+=dp[1]),其他的以此类推。
可以用二维做,但是由于该dp数组只用到了前一层的数据,可以优化为一维数组。
本代码中dp数组用a数组代替。
结果为:5484660609
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e6+10;
ll cnt;
string s;
ll a[5];
int main(){
ios::sync_with_stdio(false);
ll n,l2,t,l1,l3,l4,h=0,m,k,cnt1=0,cnt2=0,cnt3=0,flag=0,q,ma=-1;
for (int i=1;i<=2023;i++){
s=s+to_string(i);
}
for (int i=1;i<=s.size();i++){
if (s[i]=='2') a[1]++,a[3]+=a[2];
if (s[i]=='0') a[2]+=a[1];
if (s[i]=='3') a[4]+=a[3];
}
cout<<a[4];
return 0;
}