我是从大数字往小数字去枚举的,在dfs函数中先做不选择该数,然后再选择该数就过不了测试点2。如果想要过测试点2的话改变这两句话的顺序即可。
测试数据可以用100 5 2去跑一下。
至于为什么会这样解释如下:
如果不选择该数在前结果是: 100 = 5^2 + 5^2 + 5^2 + 4^2 + 3^2
如果选择该数在前结果是:100 = 6^2 + 4^2 + 4^2 + 4^2 + 4^2
原因就是如果你的代码是不选择这个数的代码在前的话就会导致你深度优先一直到从10~6都不选择,然后你选择5后你得到5 5 5 4 2的结果,此时和已经是最大22了,虽然你继续运行这个程序依然能得到6 4 4 4 4这个中间结果但是因为和是相等所以程序不会保存。如果想要消除这个影响的话你就需要在底数和相等时再进行判断,这样的话显然会大大增加程序的运行时间。
测试点5的问题:只要在dfs外计算底数的P次方的结果然后在dfs时直接用这个结果就能通过测试点5了,不要在dfs过程中去计算底数的P次方。
ps:其实你多点几次提交碰到一个好点服务器测试点5也能过。
无法通过测试点2的代码:
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int N,K,P;
vector<int> v,tmp,ans;
int maxSum = -1;
void dfs(int index,int nowK,int sumP,int sum)
{
if(nowK==K&&sumP==N){
if(sum>maxSum){
maxSum = sum;
ans = tmp;
}
return;
}
if(nowK>K||index<=0||sumP>N) return;
dfs(index-1,nowK,sumP,sum);//不选
tmp.push_back(index);
dfs(index,nowK+1,sumP+v[index],sum+index);
tmp.pop_back();
// dfs(index-1,nowK,sumP,sum);//不选
}
int main()
{
scanf("%d%d%d",&N,&K,&P);
int sqr = (int)sqrt(1.0*N);
for(int i=0; i<=sqr; i++){
v.push_back(pow(i,P));
}
dfs(v.size()-1,0,0,0);
if(ans.size()==0){
printf("Impossible\n");
return 0;
}
printf("%d = ",N);
for(int i=0; i<ans.size(); i++){
printf("%d^%d",ans[i],P);
if(i!=ans.size()-1){
printf(" + ");
}
else printf("\n");
}
return 0;
}
能通过测试点2的代码:
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int N,K,P;
vector<int> v,tmp,ans;
int maxSum = -1;
void dfs(int index,int nowK,int sumP,int sum)
{
if(nowK==K&&sumP==N){
if(sum>maxSum){
maxSum = sum;
ans = tmp;
}
return;
}
if(nowK>K||index<=0||sumP>N) return;
// dfs(index-1,nowK,sumP,sum);//不选
tmp.push_back(index);
dfs(index,nowK+1,sumP+v[index],sum+index);
tmp.pop_back();
dfs(index-1,nowK,sumP,sum);//不选
}
int main()
{
scanf("%d%d%d",&N,&K,&P);
int sqr = (int)sqrt(1.0*N);
for(int i=0; i<=sqr; i++){
v.push_back(pow(i,P));
}
dfs(v.size()-1,0,0,0);
if(ans.size()==0){
printf("Impossible\n");
return 0;
}
printf("%d = ",N);
for(int i=0; i<ans.size(); i++){
printf("%d^%d",ans[i],P);
if(i!=ans.size()-1){
printf(" + ");
}
else printf("\n");
}
return 0;
}