首页 > 其他 > 详细

noi.ac #741 code

时间:2019-10-03 19:45:28      阅读:72      评论:0      收藏:0      [点我收藏+]

挺有价值的 \(dp\) 题。

\(f[i][j]\)\(01\) 串的前 \(i\) 位构成的子串形成了 \(j\) 这个数的可能性数量。

\(i\) 进行倒序枚举,可以得到 \(dp\) 方程 :
\[ f[i][j] = f[i][j] + f[k-1][j-tmp] \]

其中 \(1\le k \le i,1 \le i \le n, 1 \le j \le m\)\(tmp\) 为剩下的部分组成的数 。

最后的答案就是 \(\sum\limits_{i=1}^mf[n][i]\)

记得取膜。。。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 998244353;
const int N = 3010;
ll n, m;
char ch[N];
ll f[N][N];//f[i][j]表示01串用前i位构成的j这个数有几种可能 
int main() {
    cin >> m;
    cin >> ch + 1;
    n = strlen(ch + 1);
    f[0][0] = 1;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            int tmp = 0;
            for(int k = i; k >= 1; k--) {
                if(ch[k] == '0') continue;
                else tmp += (1 << (i - k));//对j这个数进行拆分 
                if(tmp > j) break;
                else {
                    f[i][j] += f[k-1][j-tmp];//少一位,枚举这一位 
                    f[i][j] %= mod;
                }
            }
        }
    }
    ll ans = 0;
    for(int i = 1; i <= m; i++) ans = (ans + f[n][i]) % mod;
    printf("%lld\n",ans * 2 % mod);
    return 0;
}

noi.ac #741 code

原文:https://www.cnblogs.com/11haonb/p/11620458.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!