洛谷P1616 瘋狂的採藥
阿新 • • 發佈:2018-12-23
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了,一組沒過,才發現看錯了題。