波动序列

来源:互联网 发布:李涛疯狂淘宝靠谱吗 编辑:程序博客网 时间:2024/04/27 18:47

标题:波动数列

    观察这个数列:
    1 3 0 2 -1 1 -2 ...

    这个数列中后一项总是比前一项增加2或者减少3。

    栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?

【数据格式】
    输入的第一行包含四个整数 n s a b,含义如前面说述。
    输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。

例如,输入:
4 10 2 3
程序应该输出:
2

【样例说明】
这两个数列分别是2 4 1 3和7 4 1 -2。

【数据规模与约定】
对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。


首先,要发现这个数列的规律。假设首项就为x,那么第二项可以是x+a,x-b,假如第二项为x+a,那么第三项就是在第二项的基础上+a或-b,即x+a+a或x+a-b。所以直到最后一项,就是x+x+p+x+2p+……+x+(n-1)p,这里的p表示+a或-b,即每一次的p都有2种选择的可能。

由此我们可以发现,只要我们枚举a的个数,求出对应情况下的总和,若是s减去这个总和恰好是n的倍数,就说明此时ab的组合方法符合题目要求。结果就累加此时放置这么多a的方法数。所以接下来的问题就是求出,在a每次加1到加n的情况下,总数恰好为此时a的个数的方案数。

于是就可以想象成01背包。有编号为1-n的n个物品,每个物品的重量分别是1-n,dp[i][j]表示用前i件物品恰好塞满容量j的背包的方案数 。

#include<stdio.h>#include<string.h> #define mod 100000007using namespace std;long long dp[2][500005];//n*(n+1)/2int e, n,a, b;long long sum = 0, s;void solve()//想象成01背包。有编号为1-n的n个物品,每个物品的重量分别是1-n,dp[i][j]表示用前i件物品恰好塞满容量j的背包的方案数 {int i, j;dp[e][0] = 1;dp[e][1] = 1;for(i = 2 ; i < n ; i++){e = 1 - e;//滚动数组。因为每次都只用到上一层的dp,所以dp只保留两层即可     for(j = 0 ; j <= (i + 1) * i / 2 ; j++)    {    if(i > j)        dp[e][j] = dp[1 - e][j];    else        dp[e][j] = (dp[1 - e][j] + dp[1 - e][j - i]) % mod;    }    }}int main(){long long r;int i;scanf("%d %lld %d %d", &n, &s, &a, &b);solve();for(i = 0 ; i <= (n - 1) * n / 2 ; i++)//可供选择的a的个数最大有(1+2+……+(n-1))个,分别对应在第二个数上+a,在第三个数上+a……在第n个数上+a {r = s - i * a + (n * (n - 1) / 2 - i) * b;//算出i个a的情况下的剩余值,如果符合条件,则剩余值必定是n的倍数,系数就是首项 if(r % n == 0)    sum = (sum + dp[e][i]) % mod;}printf("%lld\n", sum);return 0;}



0 0
原创粉丝点击