题目链接
题解动态规划,思维。 又是数据量这么大。
对于第i
项,i>1
,我们都可以对第i-1
项进行+a
或-b
操作得到第i
项,最终n
个数的和要等于s
。 我们不妨将对每一项的操作表示为op
,op
有可以表示+a
操作也可以表示-b
操作,op[i]
表示第i+1
项进行的操作。
设首项即第1
项为x
,我们能够构造出的全部情况就是ss = n*x + k*a - t*b
,其中, ss
表示我们构造的数列和; k+t = 1 + 2 + …… + (n-1) = n*(n-1)/2
而我们要做的就是找到ss = s
的方案数。
我们还可以发现对第i
项进行操作时,它对整个数列之和的贡献为op*(n-i+1)
,若op=-b
,则贡献为(-b)*(n-i+1)
,若op=a
,则贡献为a*(n-i+1)
。
如果不能理解贡献的意思,我举个例子: 假设A
数列下标从1
至5
分别为 1 2 3 4 5
,和为15
对A(2)
进行-2
操作,那么后面的数字也会受到影响,数列变成1 0 1 2 3
,和为7 = 15-2*(5-2+1)
。 前面数字的变化会影响后面全部数字的变化,因为第i
项是第i-1
项经过op
操作得到的,因此改一个,其后都会受到影响。
ss = x + (x+op[1]) + (x+op[2]) + …… + (x+op[n-1])
,我们要让这个式子= s
,则有 x + (x+op[1]) + (x+op[2]) + …… + (x+op[n-1]) = s
=> n*x + op[1] + op[2] + …… + op[n-1] = s
=> (s - (op[1] + op[2] + …… + op[n-1]) ) = n*x
,这说明左边式子被n
整除 => (s - (op[1] + op[2] + …… + op[n-1]) ) / n = x
=> (s - (op[1] + op[2] + …… + op[n-1]) ) % n = 0
这就是我们最终需要的式子了,整除关系!只要满足这个整除关系就说明此时的op
数组是满足要求的。
为确定ss = n*x + k*a - t*b
中的k
,我们需要知道在数组 [1, 2, 3, ……,n-1]
中选取任意个数,其和值为 k
的组合有多少。(k
并非进行+a
操作的次数,而是+a
操作的贡献;同理,t
为-b
操作的贡献,这个必须清楚) 使用动态规划,dp[i][j]
表示前 i 个数中,和值为 j 的组合数。 递推关系,dp[i][j] = dp[i - 1][j] + dp[i - 1][j - i]
。 (由于规模较大,代码中我们使用滚动数组)
接下来我们的思路就变成了,枚举全部的k
,判断这种情况下是否满足上面的”整除关系“,若满足,我们就让答案加上枚举到的k
所包含的方案数。
#include
using namespace std;
typedef long long ll;
const int N = 1e6+10;
const ll MOD = 100000007;
ll dp[N] = {1LL};
ll ans, s, a, b;
int n;
int main()
{
cin>>n>>s>>a>>b;
for(int i = 1;i = i;j --) // 去掉一维就要逆序遍历了,与背包问题的滚动一个道理 // 前i个数相加最大才i*(i+1)/2,因此最大就从i*(i+1)/2遍历即可
dp[j] = (dp[j] + dp[j-i]) % MOD;
int m = n*(n-1)/2;
int c = a+b;
ll ss = s-m*b; // 最初我们将数列构造为ss = s-n*(n-1)/2*b,比目标s多进行了n*(n-1)/2个-b操作。
// 之所以这样做,是为了接下来我们在枚举k时,直接用ss+=(a+b)就行,这就代表了我将一个-b操作换成了+a操作
// 还不明白看这个例子,开始时ss=s-m*b,表示我们现在比s多进行了n*(n-1)/2个-b操作,接下来我们枚举k=1,
// 表示进行了1次+a操作,那么就进行 n*(n-1)/2 - 1次-b操作,此时ss变成了s+a-(n*(n-1)/2 - 1)*b,
// 这不就是s-n*(n-1)/2*b + (a+b)嘛,因此这样每次枚举k我们只需要为ss+=(a+b)就行了。
for(int i = 0;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?