• 3.28


    原题链接

    题外话

    依然不会DP (连想都没想到的一天)

    思路

    首先知道能被三整除的数字的每位数字相加的和也能被3整除

    • 之后开始DP
      • 由于我们使用上面一开始的理论, 所以当到某一位置能被三整除的时候,dp[i] 是等于前面所有可以划分的总次数(每次能被整除就可以划分一次,但是前面有可能多个能被三整除的时候,前面的可以自己在分配,所以使用递归处理)
      • 特殊考虑一下体面上说的没有前导零的情况,也就是说前导零前面的那一位是要和这个位置的零连在一起的,所以当前的次数要减去之前那一位位置的次数(等价于现在还是在之前那一位位置里面)
        注意不要忘记取余

    代码

    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    #define iinf 0x3f3f3f3f
    #define linf (1ll<<60)
    #define eps 1e-8
    #define maxn 1000010
    #define maxe 1000010
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    using namespace std;
    using namespace __gnu_pbds;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll; 
    
    ll read(ll x=0)
    {
        ll c, f(1);
        for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
        for(;isdigit(c);c=getchar())x=x*10+c-0x30;
        return f*x;
    }
    int n , k, m ;
    
    vector<int> add(vector<int> &A, vector<int> &B)
    {
        if (A.size() < B.size()) return add(B, A);
    
        vector<int> C;
        int t = 0;
        for (int i = 0; i < A.size(); i ++ )
        {
            t += A[i];
            if (i < B.size()) t += B[i];
            C.push_back(t % 10);
            t /= 10;
        }
    
        if (t) C.push_back(t);
        return C;
    }
    int f[200010];
    ll mod = 998244353;char s[100010];
    int main()
    {
    	    ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
      	 cin >>n;
      	 cin >>s+1 ;
      	 int cnt =1  , num = 0;
      	 f[0]=1 ;
      	 for(int  i=1 ;i<=n;i++){
      	   //  cout<<s[i]<<" ";
      	 	num = (s[i]-'0')+num;num%=3;
      	 	if(num!=0)continue ;
    		f[i] = cnt ;
      	 	if(s[i]=='0')cnt = (cnt - f[i-1]+ mod)%mod;
      	 	cnt = (cnt + f[i])%mod ;
      	 	//cout<<f[i] << " " << i <<endl;
    	   }
    	cout<<f[n]<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    算法竞赛入门经典第一章习题解答
    程序实现求int类型和double类型的最大最小值范围
    程序实现求int类型和double类型的最大最小值范围
    程序实现求int类型和double类型的最大最小值范围
    程序实现求int类型和double类型的最大最小值范围
    机器狗组装费用 南邮NOJ 1076 优先权队列
    【HDOJ】2604 Queuing
    【HDOJ】1208 Pascal's Travels
    【HDOJ】4857 逃生
    【HDOJ】2510 符号三角形
  • 原文地址:https://www.cnblogs.com/gaohaoy/p/12588588.html
Copyright © 2020-2023  润新知