POJ-1837 Balance
2016-06-05 11:40
344 查看
题目大意:有一个天平,单臂长15。天平上有C个位置可以用来挂砝码。有G个砝码,求将所有砝码全部挂上时使天平平衡的方法有多少种。
题目链接:http://poj.org/problem?id=1837
注意题目中几个变量的范围都不大。暴力的话是O(C^G)复杂度,最坏为20^20,肯定不行。
寻找题目的递推规律,可以知道挂一个砝码时影响天平的状态,且只与挂之前的天平状态有关。使用二维dp数组做动态规划,第一维是当前挂的砝码数量,第二维是天平状态。天平状态使用合力矩来表示。合力矩范围为[-7500,7500],可平移到[0,15000]。
初始条件:
dp[0][7500]=1 其他均初始化为0
递推式:
dp[i][j+weight[i]*loc[k]]+=dp[i-1][j]
复杂度为C*G*15000
题目链接:http://poj.org/problem?id=1837
注意题目中几个变量的范围都不大。暴力的话是O(C^G)复杂度,最坏为20^20,肯定不行。
寻找题目的递推规律,可以知道挂一个砝码时影响天平的状态,且只与挂之前的天平状态有关。使用二维dp数组做动态规划,第一维是当前挂的砝码数量,第二维是天平状态。天平状态使用合力矩来表示。合力矩范围为[-7500,7500],可平移到[0,15000]。
初始条件:
dp[0][7500]=1 其他均初始化为0
递推式:
dp[i][j+weight[i]*loc[k]]+=dp[i-1][j]
复杂度为C*G*15000
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <stdlib.h> #include <math.h> using namespace std; #define MAXN 21 #define MAXM 15001 int dp[MAXN][MAXM]; int loc[MAXN]; int weight[MAXN]; int main() { int c, g; while (~scanf("%d%d", &c, &g)) { memset(dp, 0, sizeof(dp)); for (int i = 1; i <= c; i++) scanf("%d", &loc[i]); for (int i = 1; i <= g; i++) scanf("%d", &weight[i]); dp[0][7500] = 1; for (int i = 1; i <= g; i++) { for (int j = 1; j <= 15000; j++) { for (int k = 1; k <= c; k++) { dp[i][j + weight[i] * loc[k]] += dp[i - 1][j]; } } } printf("%d\n", dp[g][7500]); } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)