题目大意:给你一个天平,并给出m个刻度,n个砝码,刻度的绝对值代表距离平衡点的位置,并给出每个砝码的重量。达到平衡状态的方法有几种。
题目思路:首先我们先要明确dp数组的作用,dp[i][j]中,i为放置的砝码数量,j为平衡状态,0为平衡,j<0左倾,j>0右倾,由于j作为下标不能是负数,所以我们要找一个新的平衡点,因为15*20*20 = 7500,所以平衡点设置为7500,
然后我们可以得出动态方程 dp[i][j+w[i]*c[k])+=dp[i-1][j];
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<stdio.h> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 1005 using namespace std; int dp[50][15100],w[MAX],v[MAX]; int main() { int i,j,k,n,m; while(scanf("%d%d",&m,&n)!=EOF) { for(i=1;i<=m;i++) scanf("%d",&w[i]); for(i=1;i<=n;i++) scanf("%d",&v[i]); memset(dp,0,sizeof(dp)); dp[0][7500]=1;//更改平衡点位置 for(i=1;i<=n;i++) { for(j=0;j<=15000;j++) { for(k=1;k<=m;k++) { dp[i][j+v[i]*w[k]]+=dp[i-1][j]; } } } printf("%d\n",dp[n][7500]); } return 0; }