逃离农场--七月牛客模拟笔试题解(二)

逃离农场

| 时间限制:2秒 | 内存限制:32768K | 语言限制: 不限
【逃离农场】牛牛在农场饲养了n只奶牛,依次编号为0到n-1, 牛牛的好朋友羊羊帮牛牛照看着农场.有一天羊羊看到农场中逃走了k只奶牛,但是他只会告诉牛牛逃走的k只奶牛的编号之和能被n整除。你现在需要帮牛牛计算有多少种不同的逃走的奶牛群。因为结果可能很大,输出结果对1,000,000,007取模。
例如n = 7 k = 4:
7只奶牛依次编号为0到6, 逃走了4只
编号和为7的有:{0, 1, 2, 4}
编号和为14的有:{0, 3, 5, 6}, {1, 2, 5, 6}, {1, 3, 4, 6},{2, 3, 4, 5}
4只牛的编号和不会大于18,所以输出5.
输入描述:输入包括一行,两个整数n和k(1 ≤ n ≤ 1000),(1 ≤ k ≤ 50),以空格分割。
输出描述:输出一个整数表示题设所求的种数。
示例1:
输入:7 4
输出:5

参考答案

作者:NotDeep
链接:https://www.nowcoder.com/discuss/208143
来源:牛客网

考虑dp[i][k][sum]表示前i个奶牛中选取k个他们的编号和为sum的方案数,于是有:
dp[i][k][sum] = dp[i - 1][k][sum] + dp[i - 1][k - 1][(sum - i + n) % n]
然后可以滚动优化或者压缩一维空间。

#include 

using namespace std;

const int mod = 1e9 + 7;
int n, k;
int dp[55][1005];
int main() {
    cin >> n >> k;
    dp[0][0] = 1;
    for(int i = 0; i < n; i++) {
        for(int j = k; j >= 1; j--) {
            for(int x = 0; x < n; x++) {
                dp[j][x] = (dp[j][x] + dp[j - 1][x - i < 0 ? x - i + n : x - i]) % mod;
            }
        }
    }
    cout << dp[k][0] << endl;
    return 0;
}

你可能感兴趣的:(程序员代码面试指南)