题目连接
正常的搜索是不容易搜索到答案的,因为无法确定最大的内个max值。但是我们可以这样考虑,首先搜索的范围是递增的。这个范围的下界是上一个数+1,上界的确定,考虑背包问题。d[i]代表拼成i最少的数是多少个。因此搜索到答案后,我们对d[i]进行计算就可以得到最大能拼成的值。
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e9;
int n,k,d[500010],a[20],ans[20],ma = 0;
int calc(int dep){
d[0] = 0;
for(int i = 1;i<=500000;i++){
d[i] = N;
for(int j = 1;j<=dep;j++){
if(i-a[j]>=0) d[i] = min(d[i-a[j]]+1,d[i]);
}
if(d[i]>n){
if(i-1>ma){
for(int i = 1;i<=dep;i++) ans[i] = a[i];
ma = i-1;
}
return i-1;
}
}
return N;
}
void dfs(int dep,int maxv){
if(dep==k){
calc(dep);
return ;
}
for(int i = a[dep]+1;i<=maxv+1;i++){
a[dep+1] = i;
int nmaxv = calc(dep+1);
dfs(dep+1,nmaxv);
}
}
int main(){
cin>>n>>k;
dfs(0,0);
for(int i = 1;i<=k-1;i++){
printf("%d ",ans[i]);
}
printf("%d\n",ans[k]);
printf("MAX=%d\n",ma);
}
这个代码有很多值得学习的地方。上下界的范围,确定最大的MAX,另外代码也非常简洁。