SRM397 CollectingMarbles

Maybe you don't know, but you are a fanatic of colored marbles. You want to collect them all, but you may not be able to carry them. You have numberOfBags bags, each of capacity bagCapacity grams. The i-th marble has a weight of marblesWeight[i] grams. You can go to the shop only once and you have enough money to buy all of the marbles. Return the largest number of marbles that you can carry home in the given bags.

題目和普通的揹包有所不同,求的是所有組合中能拿走的最大個數。而且揹包是複數個。

由於marblesWeight數組個數N<14,可以用組合計數枚舉每一種組合情況。1~1<<13。分層求1到M個揹包中拿走最多的個數比較困難,不如枚舉出每一種個數需要的最小揹包數量——事實上,兩者是一個意思。

方程是dp[i|k] = min ( dp[k] + 1) i 要求能在一個揹包裏放下,k和i互相不重疊。

class CollectingMarbles
{
	int count ( int n )
	{
		int ret = 0;
		while ( n )
		{
			if ( n & 1 )
				ret ++;
			n >>= 1;
		}
		return ret;
	}
public:
	int mostMarbles ( vector  marblesWeights, int bagCapacity, int numberOfBags )
	{
		int N = marblesWeights.size ();
		int res = 0;
		int dp[1 << 13];
		int i, j;
		rpt ( i, 1 << N )
		dp[i] = MAX;
		dp[0] = 0;
		rpt ( i, 1 << N )
		{
			int sum = 0;
			rpt ( j, N )
			{
				if ( i & ( 1 << j ) )
					sum += marblesWeights[j];
			}
			if ( sum <= bagCapacity )
			{
				//printf ( "%d/n", sum );
				rpt ( j, 1 << N )
				{
					if ( !( i & j ) )
						dp[i | j] = min ( dp[i | j], dp[j] + 1 );
				}
			}
		}
		rpt ( i, 1 << N )
		if ( dp[i] <= numberOfBags )
			res = max ( res, count ( i ) );
		return res;
	}
};
發佈了56 篇原創文章 · 獲贊 0 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章