题意:有一种新的碎纸机,要用新的碎纸机将纸条上的数字切成几部分,
求切完后的和最接近而不超过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; }
时间: 2024-10-08 20:50:28