题目大意:
给定一个形式的天枰,天枰上远离中点的不同距离拥有钩子。给定各种重量砝码,问必须悬挂所有砝码的前提下,维持天枰平衡的挂法数为多少?
暴力尝试的枚举量惊人,显然即使天枰当前不平衡,但它的“不平衡度”是可以利用的。关键是如何设计DP状态。普遍的做法是以i个物品为阶段,计算悬挂到第i个物品时,当前平衡度达到v的方法总数。易得 -7500<=v<=7500; dp[i][v]=∑dp[i-1][v-hoox[j]*w[i]] → dp[i][v+inf]=∑dp[i-1][v-hoox[j]*w[i]+inf]。常数 inf 仅为保证数组下标不为负。我们明显发现它在形式上类似于背包问题,等价于在v容背包中,尝试放入重量为hoox[j]*w[i]的物品,换取收益一种方法。
容易理解,初始解 dp[0][0+inf]=1,目标解 dp[m][0+inf] 。
类比:
http://acm.ustc.edu.cn/ustcoj/problem.php?id=1116
DD牛 << 背包九讲 >>
1
#include<cstdio>
2
#include<cstring>
3
#define G 21
4
#define N 21
5
#define inf 7500
6
7
int dp[G][inf+inf+1];
8
int w[G],h[N];
9
10
int main()
{
11
int n,m,i,j,v;
12
while(scanf("%d%d",&n,&m)!=EOF)
{
13
for(i=0;i<n;i++) scanf("%d",&h[i]);
14
for(i=1;i<=m;i++) scanf("%d",&w[i]);
15
16
memset(dp,0,sizeof(dp));
17
dp[0][0+inf]=1;
18
19
for(i=1;i<=m;i++)
20
for(v=-1*inf;v<=inf;v++)
21
for(j=0;j<n;j++)
22
if( v-h[j]*w[i]+inf+1 )
23
dp[i][v+inf]+=dp[i-1][v-h[j]*w[i]+inf];
24
25
printf("%d\n",dp[m][0+inf]);
26
}
27
return 0;
28
}
29