/*问题描述:给定一个信封,最多只允许贴 N张邮票,计算在给定K(N+K<=40) 种邮票的情况下
(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大max,使得1__max之间的每一个
邮资值都能得到。
例如:N=3,K=2,如果面值分别为1分、4分,则在1分__6分之间的每一个邮资值都能得到
(当然还有8分、9分、和12分):如果面值分别为1分、3分则在1分--7分之间的每一个邮资值都能得到。
可以验证当N=3,K=2时,7分就是可以得到的连续的邮资最大 值,所以max=7,面值分别为1分、3分。
*/
55555,似乎效率不高.............
- #include<iostream>
- using namespace std;
- #define N 3
- #define K 2
- int RStamp_Com[K];/*存储最优邮票组合*/
- int Stamp_Com[K];/*K种邮票的组合*/
- int Stamp[N];/*临时票面组合*/
- int Value[1000];/*可能的邮资值*/
- int max;
- int main(){
- void Select_Com(int value,int n);/*生成一种邮票面值组合*/
- cout<<"信封最多允许贴"<<N<<"张邮票!"<<endl;
- cout<<"邮票的面值数为"<<K<<endl;
- max=0;/*初始化最大邮资值*/
- Stamp_Com[0]=1;/*第一个邮票面值肯定要为1*/
- Select_Com(1,1);
- cout<<"则邮票票面值应该为:"<<endl;
- for(int i=0;i<K;i++)cout<<RStamp_Com[i]<<endl;
- cout<<"在此邮票组合下连续的最大邮资可达:"<<max<<endl;
- return 0;
- }
- void VALUE(int & count,int n,int sum){
- if(n==N)return;
- else{
- for(int i=0;i<K;i++){
- sum+=Stamp_Com[i];
- bool HAD=false;
- for(int j=0;j<=count;j++)if(Value[j]==sum){HAD=true;break;}
- if(!HAD){Value[count++]=sum;}
- VALUE(count,n+1,sum);
- sum-=Stamp_Com[i];
- VALUE(count,n+1,sum);
- }
- }
- }
- void Select_Com(int value,int n){
- if(n==K){/*选择了一个面值组合*/
- /*利用这个面值组合求所有可能的邮资取值*/
- for(int i=0;i<1000;i++)Value[i]=-1;
- int count=0;//计数多少种邮资值
- VALUE(count,0,0);//形成所有邮资值
- int temp_max=0;
- bool temp;
- do{
- temp=false;
- for(int i=0;i<count;i++)if(Value[i]==temp_max+1){
- temp=true;temp_max++;
- }
- }while(temp);//可能的最大邮资
- if(temp_max>max){
- max=temp_max;//修改max
- for(int k=0;k<K;k++)RStamp_Com[k]=Stamp_Com[k];
- }
- return;
- }
- else{
- for(int v=2;v<=2*N*K;v++){/*面值,这里v的最大取值存在疑问*/
- if(v>value){
- Stamp_Com[n]=v;
- Select_Com(v,n+1);
- }
- }
- }
- }