记忆化搜索(DP)—— Balance (POJ 1837)
2017-02-13 13:54
357 查看
题目链接: http://poj.org/problem?id=1837
题意: 有一个天平,左右臂各长为15,给出天平上C个挂钩的位置,再给出G个砝码的重量,问有多少种方法能使这个天平保持平衡
分析:乍看一眼我们发现这道题只能通过枚举状态来计算结果,但是状态数非常之多(GC 即 2020),不过大多状态都是重复的,所以我们可以通过把状态记录下来,减少计算量。
因为左右力矩之和最大为15000,所以我们假定7500时为平衡位置(小与7500往左偏,大于7500往右偏),这样就解决了记录状态时数组下标不能为负的问题,然后我们设我们的记录数组为DP[j]表示达到平衡状态j的有多少种方法。接着我门枚举1—G个砝码,然后枚举1-15000的平衡位置,如果DP数组里记录有值,那么就表示放上一个砝码的时候到达了这个位置,我们就可以继续在这个位置上,计算在不同挂钩处加上当前砝码后到达新的位置的方法数(这里需要枚举1-C个挂钩的位置)。我们可以发现我们至少需要2个DP数组,一个数组记录上次挂砝码的结果,一个数组则记录这次我们挂砝码的结果,2个数组可以交替使用,不过需要记得清空。初始化的时候在DP[7500]位置赋值为1,表示在7500位置时有一种平衡方法
时间复杂度为:O(G*15000*C)
AC代码:
题意: 有一个天平,左右臂各长为15,给出天平上C个挂钩的位置,再给出G个砝码的重量,问有多少种方法能使这个天平保持平衡
分析:乍看一眼我们发现这道题只能通过枚举状态来计算结果,但是状态数非常之多(GC 即 2020),不过大多状态都是重复的,所以我们可以通过把状态记录下来,减少计算量。
因为左右力矩之和最大为15000,所以我们假定7500时为平衡位置(小与7500往左偏,大于7500往右偏),这样就解决了记录状态时数组下标不能为负的问题,然后我们设我们的记录数组为DP[j]表示达到平衡状态j的有多少种方法。接着我门枚举1—G个砝码,然后枚举1-15000的平衡位置,如果DP数组里记录有值,那么就表示放上一个砝码的时候到达了这个位置,我们就可以继续在这个位置上,计算在不同挂钩处加上当前砝码后到达新的位置的方法数(这里需要枚举1-C个挂钩的位置)。我们可以发现我们至少需要2个DP数组,一个数组记录上次挂砝码的结果,一个数组则记录这次我们挂砝码的结果,2个数组可以交替使用,不过需要记得清空。初始化的时候在DP[7500]位置赋值为1,表示在7500位置时有一种平衡方法
时间复杂度为:O(G*15000*C)
AC代码:
/************************************************************************* > File Name: test.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com ************************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <cmath> #include <vector> #include <set> #include <list> #include <ctime> typedef long long LL; typedef unsigned long long ULL; typedef long double LD; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define Sqr(a) ((a)*(a)) using namespace std; #define MaxN 21 #define MaxM 15001 #define INF 0x3f3f3f3f #define bug cout<<88888888<<endl; #define MIN(x,y) (x<y?x:y) #define MAX(x,y) (x>y?x:y) template<typename _> inline void scan(_& t) { int c; while((c = getchar()) < '0' || c > '9'); t = c - '0'; while((c = getchar()) >= '0' && c <= '9') t = t * 10 + c - '0'; } template<typename _> inline void print(_ x) { int len = 0, p[20]; if(x < 0) putchar('-'), x = -x; while(x) p[++len] = x % 10, x /= 10; if(!len) p[++len] = 0; while(len) putchar(p[len--] + '0'); } int C,G; int X[MaxN]; int W[MaxN]; int DP[2][MaxM]; void solve() { DP[0][7500] = 1; int flag = 0; for(int i=1;i<=G;i++) { CLR(DP[flag^1]); for(int j=0;j<=15000;j++) { if(DP[flag][j]) { for(int k=1;k<=C;k++) { DP[flag^1][j+W[i]*X[k]] += DP[flag][j]; } } } flag^=1; } print(DP[flag][7500]); cout << endl; } int main() { scanf("%d%d", &C, &G); for(int i=1;i<=C;i++) scanf("%d", &X[i]); for(int i=1;i<=G;i++) scanf("%d", &W[i]); solve(); system("pause"); }
相关文章推荐
- POJ 1837 C - Balance(01背包)(dp)
- poj1837--Balance(dp:天平问题)
- poj 1837 Balance(DP 01背包)
- POJ-1837-Balance(dp)
- poj 1837 Balance(DP 01背包)
- poj 1837 Balance(DP)
- POJ 1837 Balance(DP)
- POJ_1837 Balance (dp)
- POJ1837 Balance(DP)
- POJ 1837 Balance (DP)
- POJ 1837 Balance (简单DP)
- Poj 1837 Balance【DP】
- poj1837——Balance(dp)
- poj 1837 Balance (DP)
- poj_1837 Balance( 線性DP模型 )
- [poj 1837]Balance dp,01背包
- poj 1837 Balance (dp,01背包)
- 文章标题 poj 1837: Balance(dp)
- POJ 1837 Balance (DP)
- poj 1837 Balance -DP