poj 3260 最少硬币(01+多重+完全背包)
http://www.cnblogs.com/ACMan/archive/2012/08/14/2637437.html
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <cctype> #include <vector> #include <iterator> #include <set> #include <map> #include <sstream> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define pf printf #define sf scanf #define spf sprintf #define pb push_back #define debug printf("!\n") #define MAXN 1010 #define MAX(a,b) a>b?a:b #define blank pf("\n") #define LL long long #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) #define pqueue priority_queue #define INF 0x3f3f3f3f int n,T; const int mx = 30000; int dp[30000],f[30000],w[30000],c[30000]; void zobag(int value,int weight) { for(int v = mx;v>=weight;v--) { dp[v] = min(dp[v],dp[v-weight]+value); } } void cmbag(int value,int weight) { for(int v = weight;v<=mx;v++) { dp[v] = min(dp[v],dp[v-weight]+value); } } void fcmbag(int value,int weight) { for(int v = weight;v<=mx;v++) { f[v] = min(f[v],f[v-weight]+value); //pf("v%d f%d\n",v,f[v]); } } void mubag(int weight,int amount) { if(weight*amount >= mx) { cmbag(1,weight); return; } int k = 1; while(k < amount) { //pf("amt%d\n",amount); //pf("k%d\n",k); zobag(k,k*weight); amount-=k; k*=2; } zobag(amount,amount*weight); } int main() { int i,j; while(~sf("%d%d",&n,&T)) { mem(dp,INF); mem(f,INF); dp[0]=0; for(i=0;i<n;i++) { sf("%d",&w[i]); } for(i=0;i<n;i++) { sf("%d",&c[i]); } for(i=0;i<n;i++) { mubag(w[i],c[i]); } f[0]=0; for(i=0;i<n;i++) { fcmbag(1,w[i]); } int ans = INF; for(i=0;i<mx-T;i++) { ans = min(ans,dp[i+T]+f[i]); } if(ans == INF) ans = -1; pf("%d\n",ans); } return 0; }