【DP】【背包】【装压】DP special train T1 天平 题解

来源:互联网 发布:淘宝店铺的日常运营 编辑:程序博客网 时间:2024/06/05 21:15

天平(balance.in/balance.out)
物理老师YJ有一个长杆天平,天平的两臂长均为15,将长杆看作x轴,则平衡点在0位置处,负数位置在左臂上,正数位置在右臂上。长杆上有n个位置有挂钩可以挂秤砣。YJ有m个秤砣,质量分别为gi,每个挂钩可以不挂也可以挂任意个秤砣。YJ想要知道,在使用所有秤砣的条件下,有多少种不同的挂秤砣的方案,可以使得天平平衡?问题太过复杂,仅凭物理知识难以解决,所以请你来帮助他。
天平的平衡条件是所有秤砣的位置质量之和为0。例如有质量为2,3,4的秤砣分别挂在-3,-2,3位置处,则2(-3) + 3*(-2) + 4*3 == 0,天平是平衡的。
【输入格式】
第一行两个数n,m。表示挂钩的数目和秤砣的数目。
第二行n个不同且递增的数,第i个数表示第i个挂钩的位置,数的范围在[-15,15]内。
第三行m个不同且递增的数,第i个数表示第i个秤砣的质量,数的范围在[1,25]内。
【输出格式】
一个整数,代表能使得天平平衡的方案数。
【输入样例】
2 4
-2 3
3 4 5 8
【输出样例】
2
【样例解释】
方案1: (-2)*(3+4+5) + 3*8 = 0
方案2: (-2)(4+8) + 3(3+5) = 0
【数据规模】
10% 数据满足2≤n,m≤4。
100% 数据满足2≤n,m≤20。
【解法】
简单的DP。考虑天平的状态可以用秤砣质量距离来表示,而题目情况下,天平的全部秤砣质量距离在(-7500,7500)(20*25*15 = 7500)以内。故可以以此状态来dp。
类似背包问题,把每一个秤砣挂在不同地方,对应成n*m个物品,转移方程f[i][j]+=f[i-1][j-dis[k]*mg[i]] (i=1..n,j=0..15000,k=1..m)。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<queue>#include<algorithm>#include<vector>#include<cstdlib>#include<cmath>#include<ctime>#include<stack>#define INF 2100000000#define LL long long#define clr(x) memset(x,0,sizeof(x))#define ms(a,x) memset(x,a,sizeof(x))#ifdef win32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;const int maxn = 25;int n,m;LL c[maxn],t[maxn];LL dp[maxn][15005];template <class T> inline void read(T &x) {    int flag = 1; x = 0;    char ch = getchar();    while(ch <  '0' || ch >  '9') { if(ch == '-')  flag = -1; ch = getchar(); }    while(ch >= '0' && ch <= '9') { x = (x<<1)+(x<<3)+ch-'0'; ch = getchar(); }    x *= flag;}int main() {    freopen("balance.in","r",stdin);    freopen("balance.out","w",stdout);    read(n); read(m);    for(int i = 1; i <= n; i++) read(t[i]);    for(int i = 1; i <= m; i++) read(c[i]);    dp[0][7500] = 1;    for(int i = 1; i <= m; i++)        for(int k = 1; k <= n; k++)            for(int j = 0; j <= 15000; j++) {                if(j-t[k]*c[i] < 0 || j-t[k]*c[i] > 15000) continue;                dp[i][j] += dp[i-1][j-t[k]*c[i]];            }    cout << dp[m][7500] << endl;    return 0;}
0 0
原创粉丝点击