题目:http://poj.org/problem?id=1416
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <map>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>
#define INF 0xfffffff
#define MAXN 100105
using namespace std;
int t,cnt;
string num;
string part[10];
string ans[10];
int len;
int anscnt, anssum;
bool rj;
int isOK(){
int sum = 0;
for(int i = 0; i < cnt; i++){
int tmp = atoi(part[i].c_str());
sum+=tmp;
}
if(sum<=t)return sum;
else return -1;
}
void dfs(int pos){
if(pos>=len){
int sum = isOK();
if(sum!=-1){
if(sum>anssum){
for(int i = 0; i < cnt; i++)ans[i] = part[i];
anscnt = cnt;
anssum = sum;
rj = false;
}
else if(sum==anssum){
rj = true;
}
}
return;
}
int subpos = pos;
for(int i = 0; i < cnt; i++){
if(part[i].length()<subpos)subpos -= part[i].length();
else{
dfs(pos+1);
string cur[10];
for(int k = 0; k < cnt; k++)cur[k] = part[k];
cnt++;
for(int k = cnt-1; k >= i+2; k--)part[k] = part[k-1];
part[i+1] = part[i].substr(subpos,part[i].length());
part[i] = part[i].substr(0,subpos);
dfs(pos+1);
cnt--;
for(int k = 0; k < cnt; k++)part[k] = cur[k];
}
}
}
int main(){
while(cin>>t>>num){
if(t==0&&num=="0")break;
part[0] = num;
ans[0] = num;
cnt = 1;
anscnt = 1;
anssum = 0;
len = num.length();
rj = false;
dfs(1);
if(anssum==0)cout<<"error\n";
else if(rj)cout<<"rejected\n";
else{
cout<<anssum;
for(int i = 0; i < anscnt; i++)cout<<' '<<ans[i];
cout<<endl;
}
}
}
总结: 一开始直接用int数组来处理分割的数字, 结果因为多个0连在一起的原因WA了, 改用字符串处理. 这题可以不做任何剪枝, 对每个间隙分两种情况: 分割和不分割, 然后对叶子节点判断就好了, sum重复则输出rejected, 无答案则error.