題意:有一種新的碎紙機,要用新的碎紙機將紙條上的數字切成幾部分,
求切完後的和最接近而不超過target的值。
比如,target的值是50,而紙條上的數字是12346,應該把數字切成四部分,
分別是1、2、34、6。所得到的和43 (= 1 + 2 + 34 + 6) 是不超過50的最大和
比如1, 23, 4, 和6 ,和爲34,比43小,
而12, 34, 6不可以,因爲它們的和超過50了。
碎紙還有以下三個要求:
1、如果target的值等於紙條上的值,則不能切。
2、如果沒有辦法把紙條上的數字切成不超過target,則輸出error。
如target是1而紙條上的數字是123,則無論你如何切得到的和都比1大。
3、如果有一種以上的切法得到最佳值,則輸出rejected。
如target爲15,紙條上的數字是111,則有以下兩種切法11、1或者1、11.
如果有且僅有一種最佳方案,則輸出最大值和切割的方案
思路:用dfs搜索每一種可能的情況,取不超過target的最大值,並記錄分割的方案
#include<stdio.h>
#include<string.h>
int ans,m,n,vis[1000000],step[10],now[10],num;
char s[10];
void dfs(int pos,int sum,int cnt)
{
int i,t;
if(pos>=m){
vis[sum]++;
if(sum>ans){
ans=sum; //記錄最佳切割的和
num=cnt;
for(i=0;i<cnt;i++) //記錄當前最佳方案
step[i]=now[i];
}
return ;
}
t=0;
for(i=pos;i<m;i++){
t=t*10+s[i]-'0';
if(sum+t>n)
return ;
now[cnt]=t;
dfs(i+1,sum+t,cnt+1);
}
}
int main()
{
int i,sum;
while(scanf("%d%s",&n,s)!=EOF){
m=strlen(s);
if(n==0&&s[0]=='0'&&m==1)
break;
sum=0;
for(i=0;i<m;i++)
sum+=s[i]-'0';
if(sum>n){ //若最小的和都大於targe,則肯定不可能切割出不超過targe的和
printf("error\n");
continue;
}
memset(vis,0,sizeof(vis));
num=ans=0;
dfs(0,0,0);
if(vis[ans]>1)
printf("rejected\n");
else{
printf("%d",ans);
for(i=0;i<num;i++)
printf(" %d",step[i]);
printf("\n");
}
}
return 0;
}