连续邮资问题
#include <iostream> #include <cstring> #define INF 0x7fffffff using namespace std; //蓝桥杯 ADV-6 //算法书上有 int a[20],n,k,MAX=0,best[20],y[10001]; //n张邮票,k种 //如何求具体的邮资区间?方法是求出y【k】=m,代表达到k的邮资最少需要m张票。 //然后顺序查看最大的y[k]<=m的序列,即为邮资区间 void f(int p,int r){ //更新上一次邮票确定后的y //当然每次更新这一次也可以,但是代码有一些变化 //因为y与具体的a的值有关,更确切的说,因为下列代码中有更新最小值,所以必须恢复y for(int i=0;i<=a[p-1]*n;i++){ //对于 i-1 所有的邮资可能 for(int j=1;j<=n-y[i];i++){ if(y[i]+j<y[i+j*a[p-1]]) y[i+j*a[p-1]]=y[i]+j; } } // int r=0; //使用了r作为参数,这样就不用每次都扫描全部了 while (y[r]<=n) r++; r--; //r即为当前区间最大值 if(p>=k){ if(r>MAX){ MAX=r; memcpy(best,a,sizeof(a)); } return; } int z[10001]; memcpy(z,y,sizeof(z)); for(int i=a[p-1]+1;i<=r+1;i++){ a[p]=i; f(p+1,r); memcpy(y,z,sizeof(z)); } } int main(){ cin>>n>>k; for(int i=0;i<=10001;i++) y[i]=INF; y[0]=0; if(k!=0){ a[0]=1; f(1,1); } for(int i=0;i<k;i++) cout<<best[i]<<" "; cout<<endl; cout<<"MAX="<<MAX<<endl; return 0; }