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];
}


發佈了94 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章