题解:搜索剪枝,特殊情况记忆化搜索,这题写了好久啊,例子:99999999999999999,这个跑出来答案有800000000。8亿,单纯的搜索肯定会t的,可以大概验证一下如果两个加数的长度不一样那么,方案数是很少的这种情况考虑搜索剪枝,而如果长度是一样的考虑记忆化搜索。那么如何剪枝呢?我们枚举一个加数(记为a)的位数最高位,那么同样知道这个加数的最低位。同理我会知道另外一个加数(记为b)的最低位(显然),那么同理b的最高位有两种情况,就是n-a这个数本身的最高位,或者是n-a这个数最高位减一(减一可能减为负数,那么这里又要分类讨论)。
这里多给几个样例:
#include
using namespace std;
typedef long long LL;
const int maxn = 1e5+7;
LL n,a[21],b[21],mul[21];
int get_num(LL x){
int num = 0;
do{
++num;
x /= 10;
}while(x);
return num;
}
bool check(){
int ed = 0;
for(int i = 18; i >= 1; i--){
if(b[i]){
ed = i;
break;
}
}
for(int i = 1,j = ed; i <= ed/2; ++i,--j){
if(b[i]/mul[i] != b[j]/mul[j]) return 0;
}
return 1;
}
inline bool judge(int l, int r){
return (b[l]/mul[l] == b[r]/mul[r]);
}
#define mp make_pair
map,LL> dp;
LL dfs(int dep, LL x, int l, int r, int bh, int len){
if(l > r){
if(!check()) return 0;
LL tx = 0, ty = 0;
for(int i = 0; i <=18; i++)
tx += a[i], ty += b[i];
if(tx + ty != n) return 0;
if(tx > 0 && ty > 0){
if(bh == len) return 1;
if(tx > ty) return 2;
else if(tx == ty) return 1;
}
return 0;
}
if(bh == len){
if(dp.count(mp(x,l))) return dp[mp(x,l)];
}
LL ans = 0;
for(int i = dep? 0 : 1; i <= 9; i++){
b[l] = b[r] = 0;
a[l] = mul[l]*i;
a[r] = mul[r]*i;
LL y = x-a[l]-a[r];
if(l == r) y += a[l];
if(y < 0) continue;
b[l] = y/mul[l]%10*mul[l];
y -= b[l];
int nbh = bh;
if(l < r){
b[r] = y/mul[r]%10*mul[r];
y -= b[r];
}
if(y >= 0 && y < mul[r]){
if(!bh && b[r] > 0) nbh = r;
if(!nbh) ans += dfs(dep+1,y,l+1,r-1,nbh, len);
else if(judge(nbh-r+1,r)) ans += dfs(dep+1,y,l+1,r-1,nbh, len);
}
if(l == r) continue;
if(b[r] >= mul[r]){
b[r] -= mul[r];
y += mul[r];
nbh = bh;
if(y >= 0 && y < mul[r]*2){
if(!bh && b[r] > 0) nbh = r;
if(!nbh) ans += dfs(dep+1,y,l+1,r-1,nbh, len);
else if(judge(nbh-r+1,r)) ans += dfs(dep+1,y,l+1,r-1,nbh, len);
}
}
else{
y += b[r];
b[r] = 9*mul[r];
y -= b[r];
if(y >= 0 && y < mul[r]*2){
if(!bh && b[r] > 0) nbh = r;
if(!nbh) ans += dfs(dep+1,y,l+1,r-1,nbh, len);
else if(judge(nbh-r+1,r)) ans += dfs(dep+1,y,l+1,r-1,nbh, len);
}
}
}
if(bh == len) dp[mp(x,l)] = ans;
return ans;
}
int main() {
cin>>n;
mul[0] = mul[1] = 1;
for(int i = 2; i <= 19; i++) mul[i] = mul[i-1]*10;
int num = get_num(n);
LL ans = 0;
ans += dfs(0,n,1,num,0, num);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
dp.clear();
ans += dfs(0,n,1,num-1,0, num-1);
cout<