http://poj.org/problem?id=1837
题意:现有一个天平,可以视为x坐标轴,负半轴为天平左边,右半轴为天平右边,
现在天平上有c个挂钩,让你挂上g个的砝码,问有几种挂法使得天平平衡,
2 <= C <= 20 ; 2 <= G <= 20 ;
挂钩坐标[-15,15] ; 砝码重量[1,25] ;
思路:试想,每次挂上一个砝码 天平的平衡度 是受 前一个砝码的位置 的影响 故 可以考虑用动态规划
可不可以把 第一个 砝码挂在不同的位置 所达到的平衡度 j 给记录下来
在已挂上 第一个砝码的所达到 平衡度为j 的基础上 再 挂第二个砝码 达到 平衡度 j‘ 记录下来
故:用 dp[i][k] 来表示 挂上 i 个砝码后 达到平衡度 j 的挂法个数 (平衡度j为0时表示天平平衡)
《
根据题意平衡度j最大时 是 把所有砝码挂在天平的一侧的最外的钩上 15*20*25 = 7500
原则上就应该有dp[ 1~20 ][-7500 ~ 7500 ]
但是下标不能为负 故 处理一下 dp[1~20][0~15000] 处理后 j为7500时 表示平衡
》
显然的 dp[0][7500]=1 是已知的
因此 dp[g][7500] 的值 就是要 求的答案
如何求: dp[ i ][ k+w[i]*l[j] ] += dp[ i-1 ][k]
w[i]表示第i个砝码的重量w[i]
l[j]表示第i个砝码所在的位置l[j]
1 #include <algorithm> 2 #include <iostream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <string> 8 #include <bitset> 9 #include <vector> 10 #include <queue> 11 #include <stack> 12 #include <cmath> 13 #include <list> 14 #include <map> 15 #include <set> 16 using namespace std; 17 /*10^8-----1s*/ 18 /***************************************/ 19 typedef vector<int> VI; 20 typedef vector<char> VC; 21 typedef vector<string> VS; 22 typedef set<int> SI; 23 typedef set<string> SS; 24 typedef map<int ,int> MII; 25 typedef map<string,int> MSI; 26 typedef pair<int,int> PII; 27 typedef vector<PII> VII; 28 typedef vector<VI > VVI; 29 /***************************************/ 30 #define min(a,b) (a>b?b:a) 31 #define max(a,b) (a>b?a:b) 32 33 #define clr(a,b) memset(a,b,sizeof(a)) 34 #define all(x) (x).begin(), (x).end() 35 #define sz(x) ((int)(x).size()) 36 #define ll long long 37 #define int64 __int64 38 #define pb push_back 39 #define mp make_pair 40 #define LL(x) ((x)<<1) 41 #define RR(x) ((x)<<1|1) 42 #define ri(x) scanf("%d",&x) 43 #define rii(x,y) scanf("%d%d",&x,&y) 44 #define rd(x) scanf("%lf",&x) 45 #define rdd(x,y) scanf("%lf%lf",&x,&y) 46 #define rs(x) scanf("%s",x) 47 #define pi(x) printf("%d",x) 48 #define pin(x) printf("%d\n",x) 49 #define ps(x) printf("%s",x) 50 #define pn() printf("\n") 51 #define sqr(x) ((x)*(x)) 52 #define rep(i,a,b) for(int i=(a);i<(b);i++) 53 #define repu(i,a,b) for(int i=(a);i<=(b);i++) 54 #define repd(i,a,b) for(int i=(a);i>=(b);i--) 55 #define repc(i,a,c) for(int i=(a);(c);i++) 56 /***************************************/ 57 const int INF = 0x7f7f7f7f; 58 const double eps = 1e-8; 59 const double PIE=acos(-1.0); 60 const int dx[]= {0,-1,0,1}; 61 const int dy[]= {1,0,-1,0}; 62 const int fx[]= {-1,-1,-1,0,0,1,1,1}; 63 const int fy[]= {-1,0,1,-1,1,-1,0,1}; 64 /***************************************/ 65 void openfile() 66 { 67 freopen("data.in","rb",stdin); 68 freopen("data.out","wb",stdout); 69 } 70 /**********************The End OF The Template*****************/ 71 72 /* 73 74 75 */ 76 77 int w[30];//w[i]表示第i个砝码的重量w[i]; i=[2~20] w[i]=[1~25] 78 int l[21];//l[j]表示第i个砝码所在的位置l[j]; l[j]=[-15~15] j=[2~20] 79 int dp[30][15002];//dp[i][k] 表示挂了i个砝码,平衡度为k的挂的种数 k=[-15*25*20,15*25*20] 80 //初始dp[0][7500]=1 81 int main() 82 { 83 int c,g; 84 int i,j,k; 85 scanf("%d %d",&c,&g); 86 for(i=0; i<c; i++) 87 { 88 scanf("%d",&l[i]); 89 } 90 for(i=0; i<g; i++) 91 { 92 scanf("%d",&w[i]); 93 } 94 memset(dp,0,sizeof(dp)); 95 dp[0][0+7500]=1;//天平在不挂钩码时,达到平衡,方法为1种 96 for(i=1; i<=g; i++) //天平上砝码的个数 97 for(k=0; k<=15000; k++) // 平衡度k 98 { 99 if(dp[i-1][k]) 100 for(j=0; j<c; j++) 101 dp[i][k+w[i-1]*l[j]]+=dp[i-1][k]; 102 } 103 printf("%d\n",dp[g][7500]); 104 return 0; 105 }
时间: 2024-10-13 08:18:19