连续邮资问题

class Stamp
{
    friend int MaxStamp(int, int, int[]);
private:
    void BackTrack(int i, int r);
    int n,			//邮票面值数
        m,			//每张信封最多允许贴的邮票数
        maxvalue,	//当前最优值
        maxint,		//大整数
        maxl,		//邮资上界
        *x,			//当前解
        *y,			//贴出各种邮资所需最少邮票数
        *bestx;		//当前最优解
};

void Stamp::BackTrack(int i, int r)
{//当前的邮票是x[i],r是x[1- i-1]邮票所能表示的最大的连续上界
    int j;
    int k;
    for(int j=0; j<=x[i]*(m-1); j++)
        if(y[j]<m)
            for(int k=1; k<=m-y[j];k++)
                if(y[j]+k<y[j+x[i]*k]) 
                    y[j+x[i]*k]=y[j]+k;
    while(y[r]<maxint) r++;//求得x[1-i]的邮票所能表示的最大连续上界
    --r;
    if(i>=n)
    {
        if(r>maxvalue)
        {
            maxvalue=r;
            for(int j=1;j<=n;j++)
                bestx[j]=x[j];
        }
        return;
    }
    int *z=new int [maxl+1];
    for(int k=1;k<=maxl;k++)
        z[k]=y[k];
    for(j=x[i]+1;j<=r+1;j++)//下一个区间的取值范围从[r+1,...],所以必须保证有值能取到r+1,因为这个区间能取到的最大连续值是r
    {
        if (y[r+1 - j] < m)
        {
            x[i+1]=j;
            BackTrack(i+1,r);//r代表当前区间能取到的最大连续值
            for(k=1;k<=maxl;k++)
                y[k]=z[k];

        }
        
    }
    delete [] z;
}

int MaxStamp(int n, int m, int bestx[])
{
    int i;
    Stamp X;
    int maxint=32767;
    int maxl=1500;
    X.n=n;
    X.m=m;
    X.maxvalue=0;
    X.maxint=maxint;
    X.maxl=maxl;
    X.bestx=bestx;
    X.x=new int [n+1];
    X.y=new int [maxl+1];
    for(int i=0;i<=n;i++)
        X.x[i]=0;
    for(i=1;i<=maxl;i++)
        X.y[i]=maxint;
    X.x[1]=1;
    X.y[0]=0;
    X.BackTrack(1,0);//这样取值比王晓东书上的更好理解了,0前一个区间能取到的最大连续值是0,这是因为前一个区间没有任何邮票的面值
    delete [] X.x;
    delete [] X.y;
    return X.maxvalue;
}

int main()
{
    int n,m;
   // cout<<"请输入邮票面值数(n)和每张信封最多允许贴出的邮票数(m):";
    while(scanf("%d%d",&n,&m))
    {
        int *bestx=new int [n+1];
        int maxvalue;
        maxvalue=MaxStamp(n,m,bestx);
        cout<<"最优解为: ";
        for(int i=1;i<=n;i++)
            cout<<bestx[i]<<"  ";
        cout<<"\n"<<"最大连续邮资区间为:"<<maxvalue<<endl;
    }
    
    return 0;
}


你可能感兴趣的:(delete,Class)