1. 程式人生 > >洛谷P1616 瘋狂的採藥

洛谷P1616 瘋狂的採藥

https://www.luogu.org/problemnew/show/P1616

完全揹包,可以用一個常數優化,對於同一個價值的量,僅儲存花費最小的那個就行了,因為每種都有無限多個。

#include<bits/stdc++.h>
using namespace std;

int n,V;
int c[10005],w[10005];
int d[100005];

int MinCost[10005],pos;

void CompletePack()
{
	for(int i=1;i<=n;i++)
	  for(int j=c[i];j<=V;j++)d[j]=max(d[j],d[j-c[i]]+w[i]); 	     
}

void init()
{
	cin>>V>>n;
	int pertime,value;
	for(int i=1;i<=n;i++)
	{
		cin>>pertime>>value;
		if(0==MinCost[value])
		{
			MinCost[value]=++pos;
			c[pos]=pertime;
			w[pos]=value;
		}
		else if(pertime<c[MinCost[value]])
		{
			c[MinCost[value]]=pertime;
			w[MinCost[value]]=value;
		}
	}
	n=pos;
}

int main()
{
	freopen("input.in","r",stdin);
	init();
	CompletePack();
	cout<<d[V]<<endl;
	
	return 0;
} 

後來想快些,看錯題本來是每個草藥價值小於10000,結果看成草藥總價值小於10000,於是想,用p(i,j)表示前i個物品價值為j用的最小花費。

初始化p(0,0)=0,p(0,j)=INF.             狀態轉移方程p(i,j)=min{p(i-1,j),p(i-1,j-w(i))+c(i)}

最後找最大的時間小於要求的價值就ok了,然後wa了,一組沒過,才發現看錯了題。