hdu 3449 Consumer(DP)

1551 단어
클릭하여 링크 열기
제목배낭에 의지하다.
물건을 살 때는 반드시 그에 상응하는 상자를 먼저 사야 한다.그리고 n개 상자의 가격과 이 상자에 담을 수 있는 물품의 가격과 가치.
최대의 가치를 추구합니다!!
일반:
dp[i][j]=dp[i][j-cost[i]]+value[i];
상자의 가치를 고려해야 한다.까닭
dp[i][j]=max(dp[i-1][j],max(dp[i-1][j-k]+pack[i][k]));
그 중에서 dp[i][j]는 전 i개의 상자를 사용하여 j가 얻은 최대 가치를 나타낸다.i번째 상자를 도대체 고를지 안 고를지 고려하면 얼마를 더 써야 하는지 시간 복잡도가 높기 때문에 최적화한다.
자세히 분석하면 dp[i-1][j-k]+pack[i][k]가 i번째 상자를 고려하는 상황에서 가장 큰 가치를 발견할 수 있다.
상자의 가치를 0으로 간주하고 금전j에서 먼저 상자의 가격을 고려하면 나머지는 상자 속의 물품, 즉 01배낭만 고를 수 있다.
f(i, j)를 이전 i개의 상자로 하고 i개를 반드시 고려한 상황에서 가장 큰 가치로 초기화하기 때문에 f(i, j)=max(f[i][j-box[i]+0)(PS: 초기화하면 상자의 영향이 없어진다).그리고 01이면 돼!
#include"stdio.h"
#include"string.h"
#define max(x,y) x>y?x:y;
int dp1[100001];
int dp2[100001];
int main()
{
	int n,w,i,j,k;
	int cost[55][11],value[55][11];
	int num[55],box[55];
	while(scanf("%d%d",&n,&w)!=-1)
	{
		for(i=1;i<=n;i++)
		{
			scanf("%d",&box[i]);
			scanf("%d",&num[i]);
			for(j=1;j<=num[i];j++)
				scanf("%d%d",&cost[i][j],&value[i][j]);
		}
		memset(dp1,0,sizeof(dp1));
		for(i=1;i<=n;i++)
		{
			for(j=w;j>=box[i];j--)
				dp2[j]=dp1[j-box[i]];//   ,       !!
			for(j=1;j<=num[i];j++)
			{
				for(k=w;k>=cost[i][j]+box[i];k--)
					dp2[k]=max(dp2[k],dp2[k-cost[i][j]]+value[i][j]);
			}
			for(j=w;j>=box[i];j--)
				dp1[j]=max(dp1[j],dp2[j]);//  dp1
		}
		printf("%d
",dp1[w]); } return 0; }

좋은 웹페이지 즐겨찾기