1. 程式人生 > >DP 動態規劃 Problem S 1019 簡單揹包

DP 動態規劃 Problem S 1019 簡單揹包

Problem S  ID:1019

簡單題意:給出若干組裝置的數目和價值,儘量使其價格平分成兩部分,如果不能平分,分成的前一部分不能低於第二部分。問:分成兩部分後,第一部分的價格和第二部分的價值分別是多少。

解題思路形成過程:比較簡單的01揹包問題,需要注意的是對輸入各類裝置價格和數量的操作。

            在DP的兩重迴圈中,內層迴圈應當是從sum/2(sum是所有裝置的總價)開始。

            狀態轉移方程式為:dp[j]=max(dp[j],dp[j-item[i]]+item[i])。

            遍歷結束後,第一部分的價值為:sum-dp[sum/2],
第二部分的價值為:dp[sum/2]。

感想:注意輸入部分的微操,注意陣列大小。

程式碼:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[250001];
int item[5001];
int n,v,m,cnt,t,sum;
int main()
{
	//freopen("1.txt","r",stdin);
	while(scanf("%d",&n)!=EOF&&n>0)
	{
		memset(dp,0,sizeof(dp));
		cnt=0;
		t=0;
		sum=0;
		for(int i=1;i<=n;++i)
		{
			scanf("%d%d",&v,&m);
			cnt+=m;
			while(m--)
			{
				item[t++]=v;
				sum+=v;
			}
		}
		for(int i=0;i<cnt;++i)
			for(int j=sum/2;j>=item[i];--j)
				dp[j]=max(dp[j],dp[j-item[i]]+item[i]);
		printf("%d %d\n",sum-dp[sum/2],dp[sum/2]);
	}
	return 0;
}