poj 1837 Balance(简单dp)
题意:给你一架天平,C个挂钩位置和G个砝码,让你将这G个砝码全部用上,求有多少种方法使得天平平衡。
思路:读完题后根本没有思路,如果让我自己想,我绝不会想到用dp做,但是这题是在背包问题的练习题里的,并且刚刚看完0-1背包,对dp有了一点理解,所以不难想到用dp做。可是,最后却在数组范围上卡了一下,想不明白为什么要开到15000,想了两天后,终于明白,力矩等于力臂*重量,而砝码的个数最多为20个,力臂最长为15,要使天平平衡的左右两边的重量为15*20*20 =7500,所以要开15000;
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #include <queue> #define maxn 15000 #define maxm 21 using namespace std ; int dp[maxm][maxn] ; int main() { int n , m , i , j , k ; int a[maxm] , b[maxm] ; while ( scanf ( "%d%d" , &n , &m ) != EOF ) { for ( i = 1 ; i <= n ; i++ ) scanf ( "%d" , &a[i] ); for ( i = 1 ; i <= m ; i++ ) scanf ( "%d" , &b[i] ); memset( dp , 0 , sizeof ( dp )); dp[0][maxn/2] = 1 ; for ( i = 1 ; i <= m ; i++ ) for ( j = 1 ; j <= maxn ; j++ ) if ( dp[i-1][j] ) { for ( k = 1 ; k <= n ; k++ ) dp[i][j + a[k] * b[i]] += dp[i-1][j]; } printf ( "%d\n" , dp[m][maxn/2] ); } return 0; }