Codeforces #247 (Div. 2) C. k-Tree

来源:互联网 发布:制冷剂充注量计算软件 编辑:程序博客网 时间:2024/05/20 07:59

题意就不说了

我上来就用暴力回溯写了,这几天练暴力练得脑残了尴尬

暴力的代码如下:

#include <cstdio>#include <iostream>#include <algorithm>#define MAXN 10010#define ll long longusing namespace std;int n, k, d;int maxs, sum;int a[MAXN];ll tot;void search(int cur) {    if(sum >= n) {        if(sum == n) {            for(int i=0; i<cur; ++i)                maxs = max(maxs, a[i]);//            cout << "maxs = " << maxs << endl;            if(maxs>=d && maxs <=k) {                tot++;                /*                for(int i=0; i<cur; ++i) {                    cout << a[i] << " ";                }                cout << endl;                */            }        }        maxs = -1;    }    else {        for(int i=1; i<=n; ++i) {            a[cur] = i;            maxs = max(maxs, i);            sum += i;            search(cur+1);            sum -= i;        }    }}int main(void) {    while(cin >> n >> k >> d) {        sum = 0;        tot = 0;        maxs = -1;        search(0);        cout << tot%(1000000007) << endl;    }    return 0;}

第5个样例就TLE了

今天看别人的代码才看懂

用递推做的

先找到所有和为n,n拆分后的加数最大项小于等于k的情况总个数ans1

然后找到所有和为n, n拆分后的加数最大项小于d的情况总个数ans2

然后输出((ans1-ans2)%(1e9+7)+(1e9+7))%(1e9+7)

代码如下:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAXN 110#define ll long long#define MASK 1000000007using namespace std;ll f1[MAXN][MAXN];ll f2[MAXN][MAXN];int main(void) {    int n, k, d;//    f[i][j]表示把和为j的数拆分成i项有多少种情况    while(cin >> n >> k >> d) {        memset(f1, 0, sizeof(f1));        for(int i=1; i<=k; ++i) {            f1[1][i] = 1;        }        for(int i=2; i<=n; ++i) {            for(int j=2; j<=n; ++j) {                int t = min(j, k);                for(int l=1; l<=t; ++l) {                    f1[i][j] = (f1[i][j]+f1[i-1][j-l])%MASK;                }            }        }        memset(f2, 0, sizeof(f2));        for(int i=1; i<d; ++i)            f2[1][i] = 1;        for(int i=2; i<=n; ++i) {            for(int j=2; j<=n; ++j) {                int t = min(j, d-1);                for(int l=1; l<=t; ++l) {                    f2[i][j] = (f2[i][j]+f2[i-1][j-l])%MASK;                }            }        }        ll ans = 0;        for(int i=1; i<=n; ++i) {            ans += f1[i][n];        //    cout << "f1[" << i << "][" << n << "] = " << f1[i][n] << endl;        }        for(int i=1; i<=n; ++i) {            ans -= f2[i][n];        //    cout << "f2[" << i << "][" << n << "] = " << f2[i][n] << endl;        }        cout << (ans%MASK+MASK)%MASK << endl;    }    return 0;}


0 0
原创粉丝点击