题目链接:
题意:
有一个最大长度为15的天平,上面有C个挂钩(左边的坐标为负,右边的坐标为正),现在有G个砝码,问将所有砝码挂上有多少总挂法能使天平平衡。
题解:
我们可以拿着砝码模拟一下操作,便可以得到这么一个状态转移方程:dp【i】【j】表示前i个砝码产生平衡位置为j的种数,dp【i】【j】 += dp【i-1】【j-c【m】*g【n】】(1<=m<=C, 1<=n<=i)
但是由于j可能负,所以要将未放砝码时的平衡位置右移,因为负值最大为15*20*25=7500,所以7500为一开始的平衡位置,dp【0】【7500】=1
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#include <string.h>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<time.h>
using namespace std;
#define MAX_N 100005
#define inf 0x3f3f3f3f
#define LL long long
#define ull unsigned long long
const LL INF = 9e18;
const int mod = 1e8+7;
typedef pair<LL, LL>P;
int main()
{
int C, G;
cin >> C >> G;
int c[25], g[25];
for(int i=1; i<=C; i++)
cin >> c[i];
for(int i=1; i<=G; i++)
cin >> g[i];
int dp[25][15005];
dp[0][7500] = 1;
for(int i=1; i<=G; i++) {
for(int j=1; j<=C; j++) {
for(int k=15000; k>=0; k--) {
if(k-c[j]*g[i]>=0 && k-c[j]*g[i]<=15000)
dp[i][k] += dp[i-1][k-c[j]*g[i]];
/*if(dp[i][k])
printf("%d %d %d\n",i,j,k-7500);*/
}
}
}
printf("%d\n",dp[G][7500]);
}