标签:balance int POJ1837 砝码 maxn 平衡 Balance dp
POJ1837-Balance
题目链接:https://vjudge.net/problem/POJ-1837
题意:给你一根杠杆,轴在中心标记位0,中心左边,从左到右标记-15,-14,…,-1,中心右端,1,2,3,…,15,表示到中心的距离。现在给你c个挂钩,g个砝码。告诉你挂钩位置和每个砝码的重量,要求用完所有砝码。问:使得杠杆平衡的方案数是多少?
思路:动态规划。首先定义平衡度 b a l a n c e = Σ w [ i ] ∗ c [ k ] balance=Σw[i]*c[k] balance=Σw[i]∗c[k],w是砝码重量,c是砝码位置,显然当balance=0时,杠杆是平衡的。balance>0右端低,balance<0左端低。
定义: d p [ i ] [ j ] dp[i][j] dp[i][j]表示使用前i个砝码时,平衡度达到j时杠杆平衡的方案数。
放了i-1个砝码,平衡度为j时,状态为dp[i-1][j].
现在放第i个砝码:平衡度变为 j→j+w[i]*c[k].
此时放了i个砝码,平衡度为j+w[i]*c[k],状态为dp[i][j+w[i]*c[k]].
因为,末状态dp[i][j+w[i]*c[k]]可能由多个初状态得到所以要对dp[i-1][j]求和,不难得到
状态转移方程:
dp[i][j+w[i]*c[k]]=Σdp[i-1][j].
规划方向:采用自顶向下的方式。来求dp。循环变量及顺序(由外到内):j->w->c
目标答案:dp[cnt_w][7500]。(砝码用完时的平衡方案数)
代码:
#include<iostream>
using namespace std;
const int maxn=27;
int dp[maxn][15001];
int w[maxn];
int c[maxn];
int main(){
int n_c,n_w;
cin>>n_c>>n_w;
int i;
for(i=1;i<=n_c;i++)cin>>c[i];
for(i=1;i<=n_w;i++)cin>>w[i];
dp[0][7500]=1;
int j,k;
for(i=1;i<=n_w;i++){
for(j=0;j<=15000;j++){
for(k=1;k<=n_c;k++){
if(j+w[i]*c[k]>=0)dp[i][j+w[i]*c[k]]+=dp[i-1][j];
}
}
}
cout<<dp[n_w][7500]<<endl;
return 0;
}
动态规划过程:
1.相关变量(如本题的w,c,平衡度,方案数)
2.定义dp(一维还是两维?dp i j的意思?)
3.暴力枚举简单解,确定状态转移方程
4.确定规划方向 ↑还是↓
5.目标答案的表达(放到第三步也行)
标签:balance,int,POJ1837,砝码,maxn,平衡,Balance,dp 来源: https://blog.csdn.net/lovelyfather/article/details/121257936
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。