也是个方程
【问题描述】
已知 c 和a1,…,an全都是正整数,求满足a1*b1+a2*b2+…+an*bn=c的非负整数解{b1,b2,…,bn}的组数。
【输入】
第一行是 n 和c。
第二行是 n 个数,分别表示1,…, n a a。
【输出】
输出解的组数(结果对 999983 取模)。
【输入样例】
2 4
1 2
【输出样例】
3
【数据规模】
30%的数据中n≤10,c≤100;
100%的数据中n≤100,c≤10^5。
【一句话题意】
题中貌似仍然只有一句话。。。
【考察知识点】
动态规划
【思路】
这道题目比较纠结,一直想不到用无限背包模型求解。
假设前i个数的和为j时,解的个数为f[j],则可以得到以下转移方程(滚动数组版):
f[j]:=f[j]+f[j-a[i]] (1<=i<=n,a[i]<=j<=c)
因为是无限背包,所以要注意循环顺序。
【提交过程】
WA=>AC
【时间复杂度】
O(n*c)
【代码】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
//uses sysutils;
Const
ProgramName=
'muti'
;
Var
i,j,k,n,m,l,r,s,t,x,y:
longint
;
a:
array
[
0..110
]
of
longint
;
f:
array
[
0..100100
]
of
int64
;
ans:
int64
;
c:
longint
;
Procedure
Pin;
var
i,j,k:
longint
;
begin
readln(n,c);
for
i:=
1
to
n
do
read(a[i]);
readln;
end
;
Procedure
Main;
var
i,j,k:
longint
;
begin
fillchar(f,sizeof(f),
0
);
f[
0
]:=
1
;
for
i:=
1
to
n
do
for
j:=a[i]
to
c
do
f[j]:=(f[j]+f[j-a[i]])
mod
999983
;
end
;
Procedure
Pout;
var
i,j,k:
longint
;
begin
writeln
(f[c]
mod
999983
);
end
;
begin
assign(input,ProgramName+
'.in'
);
assign(output,ProgramName+
'.out'
);
reset(input);
rewrite(output);
//time:=now;
pin;
main;
pout;
//writeln((now-time)*86400000:8:8);
close(input);
close(output);
end
.
|