題目大意:
將一串數字分成若干個部分 ( 例如12346) 求其中和不超過數字 n (例50) 的最大值。
比如說 12346 可以分成 12+34+6 = 52 1+2+34+6 = 43
其中43滿足,52不滿足,因爲不允許超過。
注意:
1、123 可以拆成 1+23 12+3 ,但13+2是不允許的。 21+3,32+1也不允許。 其實題目很簡單
2、如果怎麼分都比n大,輸出error
3、如果有超過一種以上的切法,輸出rejected 比如 n=12 , 數字串爲111 11+1 和1+11示威兩種不同的切法。
還能怎麼辦,搜索!
#include <iostream>
#include <cstring>
#include <string>
#define N 1000
using namespace std;
int arr[N]; //數字
int temp[N]; //臨時的保存數組
int save[N]; //保存最優
int hash[N*N]; // 查看訪問過幾次
int flag = 1;
int n;
int cnt = 0;
int sz = 0;
int maxs = 0;
string str;
void dfs(int ans,int step,int t)
{
if(step >= sz)
{
if (ans > maxs)
{
maxs = ans;
for (int i = 0; i <t ; ++i) //更新最優
save[i] = temp[i];
cnt = t;
}
hash[ans] ++; //訪問+1
return;
}
int save_ans = ans;
int i = t-1;
if (i >= 0){
ans += temp[i]*9 + arr[step]; //第一種,直接接在後面 ,此時增加量爲temp[i]*9+ar[step]很好想到
temp[i] = temp[i]*10 + arr[step]; //更新temp[i]值。
if(ans<=n)
dfs(ans,step+1,t);
temp[i] = temp[i] / 10;
ans = save_ans;
}
if(ans+arr[step] <= n) //第二種 獨立分開
{
temp[t] = arr[step];
ans += temp[t];
dfs(ans,step+1,t+1);
}
}
int main()
{
while(cin >> n >>str)
{
memset(hash,0,sizeof(hash));
if (n == 0 ) break;
maxs = -999;
cnt = 0;
flag = 1;
sz = str.size();
for (int i = 0; i < sz ; ++i)
arr[i] = str[i] - '0'; //拆數字
dfs(0,0,0);
if(maxs >= 0 && hash[maxs] >= 2)flag = -1;
maxs *= flag;
if (maxs >= 0)
{
printf("%d ",maxs);
for (int i = 0 ; i < cnt ; ++i)
printf("%d ",save[i]);
printf("\n");
}
else
{
if (flag == 1)
printf("error\n");
else
printf("rejected\n");
}
}
}
其實覺得有點動歸的影子。集合類動歸