设要付的钱是M,存在一个付钱的上限V,对于0到V是一个多重背包问题(每种货币有限制数量)
对于给多的部分, 即V-M,由于还钱时候,每种货币没有数量限制,是一个完全背包问题。
参考这篇文章,
http://www.cppblog.com/Davidlrzh/articles/135614.html证明了,V 最大为 M + v[i]*v[i]  (v[i]是货币中最大价值的一个)
 #include <iostream>
#include <iostream>

 using namespace std;
using namespace std;

 const int MAXN    = 25000;
const int MAXN    = 25000;
 const int MAX    = 105;
const int MAX    = 105;
 const int INF    = 99999;
const int INF    = 99999;

 int v[MAX], n[MAX];
int v[MAX], n[MAX];
 int f[MAXN], g[MAXN];
int f[MAXN], g[MAXN];

 int V,N;
int V,N;


 void ZeroOnePack(int c, int w, int dp[])
void ZeroOnePack(int c, int w, int dp[]) {
{
 for(int v=V; v>=c; --v)
    for(int v=V; v>=c; --v)
 if(dp[v-c]+w < dp[v])
        if(dp[v-c]+w < dp[v])
 dp[v] = dp[v-c]+w;
            dp[v] = dp[v-c]+w;
 return;
    return;
 }
}


 void CompletePack(int c, int w, int dp[])
void CompletePack(int c, int w, int dp[]) {
{
 for(int v=c; v<=V; ++v)
    for(int v=c; v<=V; ++v)
 if(dp[v-c]+w < dp[v])
        if(dp[v-c]+w < dp[v])
 dp[v] = dp[v-c]+w;
            dp[v] = dp[v-c]+w;
 return;
    return;
 }
}


 void MultiplePack(int c, int w, int m, int dp[])
void MultiplePack(int c, int w, int m, int dp[]) {
{

 if(m*c>=V)
    if(m*c>=V) {
{
 CompletePack(c, w, dp);
        CompletePack(c, w, dp);
 return;
        return;
 }
    }
 int k=1;
    int k=1;

 while(k<m)
    while(k<m) {
{
 ZeroOnePack(k*c, k, dp);
        ZeroOnePack(k*c, k, dp);
 m-=k;
        m-=k;
 k*=2;
        k*=2;
 }
    }
 ZeroOnePack(m*c, m, dp);
    ZeroOnePack(m*c, m, dp);
 }
}

 int M;
int M;


 int main()
int main() {
{
 int i, max=0;
    int i, max=0;
 cin>>N>>M;
    cin>>N>>M;


 for(i=1; i<=N; ++i)
    for(i=1; i<=N; ++i) {
{
 cin>>v[i];
        cin>>v[i];
 if(v[i]>max)
        if(v[i]>max)
 max=v[i];
            max=v[i];
 }
    }

 for(i=1; i<=N; ++i)
    for(i=1; i<=N; ++i)
 cin>>n[i];
        cin>>n[i];

 V = M + max*max;
    V = M + max*max;

 for(i=1; i<V; ++i)
    for(i=1; i<V; ++i)
 f[i] = INF;
        f[i] = INF;

 for(i=1; i<=N; ++i)
    for(i=1; i<=N; ++i)
 MultiplePack(v[i], 1, n[i], f);
        MultiplePack(v[i], 1, n[i], f);

 V = max*max;
    V = max*max; 

 for(i=1; i<V; ++i)
    for(i=1; i<V; ++i)
 g[i] = INF;
        g[i] = INF;

 for(i=1; i<=N; ++i)
    for(i=1; i<=N; ++i)
 CompletePack(v[i], 1, g);
        CompletePack(v[i], 1, g);

 V = M+max*max;
    V = M+max*max;
 int min = INF;
    int min = INF;
 for(i=M; i<V; ++i)
    for(i=M; i<V; ++i)
 if(f[i]+g[i-M]<min)
        if(f[i]+g[i-M]<min)
 min = f[i]+g[i-M];
            min = f[i]+g[i-M];

 if(min!=INF)
    if(min!=INF)
 cout<<min<<endl;
        cout<<min<<endl;
 else
    else
 cout<<-1<<endl;
        cout<<-1<<endl;

 return 0;
    return 0;
 }
}


posted on 2010-12-23 13:10 
小阮 阅读(327) 
评论(0)  编辑 收藏 引用  所属分类: 
POJ