poj-1837 Balance【dp】

题目大意:

有一个天平,天平左右两边各有若干个钩子,总共有C个钩子,有G个钩码,求将钩码全部挂到钩子上使天平平衡的方法的总数。

其中可以把天枰看做一个以x轴0点作为平衡点的横轴

输入:

2 4 //C 钩子数 与 G钩码数

-2 3 //负数:左边的钩子距离天平中央的距离;正数:右边的钩子距离天平中央的距离c[k]

3 4 5 8 //G个重物的质量w[i]

 臂力=力距*重量

把每个臂力都当做一个单元。定义一个臂力和j,j的范围是【-25*15*20,25*15*20】力距*重量*极限个数

对每个臂力单元+25*15,那么j的范围就成了[0,15000],而平衡点在7500处;

设dp[j][i]表示放第i个物品时总臂力和为j时能有多少种方法

 dp[j-臂力单元][i]+=dp[j][i-1]

所以三重循环为:

for( i =1;i<=g;++i)

for(k=1;k<=c;++k)

for(int j=0;j<=15000;++j)

{

if(j+pos[k]*w[i]>=0&&j+pos[k]*w[i]<=15000)

dp[j+pos[k]*w[i]][i]+=dp[j][i-1]

}

但是当dp[j][i-1]=0时;

for(k=1;k<=c;++k) 的循环是多余的,而把j的循环放在k前,对结果不影响。

所以有

int solve()
{
	memset(dp,0,sizeof(dp));
	dp[mid][0]=1;
	for(int i=1;i<=g;++i)
		for(int j=0;j<=MAX_DP;++j)
		{
			if(dp[j][i-1])//dp[j][i-1]有效时,j+pos[k]*w[i]肯定不会越界
			{
				for(int k=1;k<=c;++k)
					dp[j+pos[k]*w[i]][i]+=dp[j][i-1];
			}
		}
	return dp[mid][g];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值