题目大意: 一个天平,给你一些挂钩(固定的),砝码,要求砝码全用,挂钩可以只用一些,砝码在天平上的效果等于挂钩距离中心点的距离与砝码重量的乘积。
Input:
2 4
-2 3
3 4 5 8
输入样例分析:
第一行:2 代表挂钩数量 4 代表砝码数量
第二行:挂钩与中心点的距离(负的代表在中心点左边,正的当然是右边)
第三行: 砝码的重量
解题思路:因为砝码需要全用,所以我们枚举放进每个砝码的情况,记录放入每个砝码的情况。
int dp[25][15100], eg: dp[i][j] 放入第 i 个砝码时, j为中心点两边的值, j 为7500 时天平平衡,因为天平每一边最多放7500(砝码*挂钩距离)。
Eg: a[2][0] 就是放入第二个砝码左边减右边的值为7500(砝码*挂钩距离之和); a[2][7500] 平衡 ; a[2][1500] 右边减左边的值7500。
代码如下:
#include<stdio.h>
#include<string.h>
int dp[25][15100]; //记录放入每个砝码的情况
int hook[30], w[30]; //hook[] 记录挂钩 w[]记录砝码
int main()
{
int c, g;
scanf("%d %d",&c,&g); // c 挂钩数量 g 砝码数量
int i, j;
for(i=1; i<=c; i++)
scanf("%d",&hook[i]);
for(i=1; i<=g; i++)
scanf("%d",&w[i]);
memset(dp,0,sizeof(dp)); // 初始化
dp[0][7500]=1; // 当不放砝码时,天平平衡, 所以标记dp[0][7500]为 1
for(i=1; i<=g; i++) //不断放入每个砝码
for(j=1; j<=15000; j++) // 枚举天平的每个状态
{
if(dp[i-1][j]>0) // 如果上一种情况成立
{
for(int k=1; k<=c; k++) //在上一种情况成立的情况下枚举各个挂钩
{
dp[i][j+hook[k]*w[i]]+=dp[i-1][j]; //记录情况
}
}
}
printf("%d",dp[g][7500]);
return 0;
}