Program Stamp;
Const
Maxn=40;
Var
Value,BestValue : Array[1..Maxn] Of Integer;
Max,N,K : Integer;
{If N=5,K=5 Value[]=(1,4,9,31,51), It returns 126, Got it?}
Function Cont(x:Integer):Integer;
Var
I:Integer;
CanGet:Array[0..10000] Of Boolean;
Count:Array[1..Maxn] Of Integer;
Procedure UseIt(Num,Left:Integer);
Var
I:Integer;
Total:Integer;
Begin
If Num=x+1 Then
Begin
Total:=0;
For I:=1 to x Do Inc(Total,Value[i]*Count[I]);
CanGet[Total]:=True;
Exit;
End;
For I:=0 to Left Do
Begin
Count[Num]:=I;
UseIt(Num+1,Left-I)
End;
End;
Begin
Fillchar(CanGet,SizeOf(CanGet),0);
UseIt(1,n);
I:=1; While CanGet[i] Do Inc(I); Cont:=I-1;
End;
(*
This is the most important part
eg: N=3,K=3
Suppose we're searching for the 3rd stamp while the first two are 1,4
We got:
1 = 1
2 = 1+1
3 = 1+1+1
4 = 4
5 = 1+4
6 = 1+1+4
Then we call:
Find(5,7,3); that means, we should find a value for the 3rd stamp
from 5,6,7,8..., the first two stamps could get value 1..7-1.
Got it?
*)
Procedure Find(FindStart,ContStart,x:Integer);
Var
I:Integer;
ContMost:Integer;
Begin
If x=k+1 Then
Begin
If Max < ContStart-1 Then
Begin
Max := ContStart-1; {Hey, ContStart is NOT the largest number we really got!}
For I:=1 to K Do BestValue[I]:=Value[I]; {Copy to BestValue}
End;
Exit;
End;
I:=FindStart;
While True Do
Begin
Value[x]:=i;
ContMost:=Cont(x); {Calculate}
Find(I+1,ContMost+1,x+1);
If I+1>ContStart Then Exit Else Inc(I);
{if I+1>ContStart we CANNOT get value Constart 'cause I will be bigger and bigger}
End;
End;
Procedure Init;
Begin
Max:=0; {Initialize}
Write('N='); Readln(N);
Write('K='); Readln(K);
Value[1]:=1; {The 1st Stamp Must Be 1 ^_^}
End;
Procedure Answer;
Var I:Integer;
Begin
For I:=1 to K Do Write(BestValue[I],' ');
WriteLn;
WriteLn('MAX=',Max);
End;
Begin
Init;
Find(2,n+1,2); {Search From the 2nd Stamp}
Answer;
End.
#define INPUT_FILE "stamp.in" // input file name
#define OUTPUT_FILE "stamp.out" // output file name
#define MAX_N 40
#define true 1
#define false 0
FILE *fin, *fout; // inout file and output file
int ProbN = 0; // the No. of input case
int n, k;
/*
stamp is current solution,
value[i][j] is the max value that using j pieces of stamp[0]..stamp[i] will get
best is the best solution
*/
int stamp[MAX_N], value[MAX_N], best[MAX_N];
int MaxValue; // the max value of the best solution
int ReadCase()
{
if (feof(fin))
return false;
/*
TO DO: add some code here to read input data
*/
fscanf(fin, "%d%d", &n, &k);
if (n <= 0)
return false;
ProbN++;
return true;
}
int CanGet(int depth, int Y, int total)
{
if (depth == 0)
return (Y <= total);