这道题又是一道简单典型的背包问题,然而并不是很好想到怎么写;
这种老题目相比较cf题意有点晦涩~orz
主要讲的是给你一个天平,天平的两边一共有C个挂钩,再给你G个重量不同的物体,要求把物体全挂在两边的钩子上,要使天平平衡,问有多少种方案。挂的时候是用距离*重量来计算平衡,由于给的物体重量和个数都比较小,就可以用01背包来解决,遍历G个物体,考虑该物体是否挂在第Ci个钩子上,当重量为0的时候即为平衡。但是重量为负数的时候不好用数组存,就都加最大范围的重量,即7500 = 15(钩子距离)*25(重量范围)*20(物体的个数);
设dp[i][j],i表示物体i,j表示天平加上当前物体*距离的重量,dp[i][j]的值表示方案数,初始化dp[0][7500] = 1,表示什么都不放有一种方案。最后只要输出dp[G][7500],即为G个物体全放完、且保持平衡的方案数。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int c[25],w[25],dp[25][15005]; //dp存方案数
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
scanf("%d",&c[i]);
for(int i = 1;i <= m;i++)
scanf("%d",&w[i]);
memset(dp,0,sizeof(dp)); //初始化每个状态方案数为0
dp[0][7500] = 1; //什么都不放有一种方案
for(int i = 1;i <= m;i++)
for(int j = 0;j <= 15000;j++)
if(dp[i-1][j]) //如果重量为j的时候存在方案,就加进算上w[i]*c[k]后的方案数内
for(int k = 1;k <= n;k++)
dp[i][j + w[i]*c[k]] += dp[i-1][j];
printf("%d\n",dp[m][7500]);
}