#include<bits/stdc++.h>
// #define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define fv(i,p) for(int i=0;i<p.size();++i)
#define ptc putchar
#define il inline
#define reg register
// #define push_back pb
// #define mp make_pair
// #define eb emplace_back
// #define ret; return 0;
using namespace std;
const int S=55;
const int T=100005;
const int MOD=998244353;
const int INF=0x7f7f7f7f;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int Max(int a,int b){return a>b?a:b;}
int MAX(int a,int b,int c){return Max(a,Max(b,c));}
int Min(int a,int b){return a<b?a:b;}
int MIN(int a,int b,int c){return Min(a,Min(b,c));}
void Swap(int&a,int&b){int tmp=a;a=b;b=tmp;}
void cmin(int&x,int y){if(x>y)x=y;}
void cmax(int&x,int y){if(x<y)x=y;}
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*f;
}
int t,n,num[S][S],f[S][T];
string s;
void solve(){
cin>>s>>t;n=s.size();
memset(f,INF,sizeof(f));
f[0][0]=-1;
rep(i,1,n)rep(j,1,i){
if(num[j][i-1]>t)num[j][i]=INF;
else num[j][i]=num[j][i-1]*10+(s[i-1]-48);
}
rep(i,1,n)rep(s,0,t)for(int j=i-1;j>=0&&num[j+1][i]<=t;--j){
if(s>=num[j+1][i]){
cmin(f[i][s],f[j][s-num[j+1][i]]+1);
}
}
cout<<(f[n][t]<INF?f[n][t]:-1);
}
signed main(){
// freopen(,,stdin);
// freopen(,,stdout);
ios::sync_with_stdio(0);
cin.tie(0);
solve();
return 0;
}
思路如下:
记 numi,j 为 第 i 位到第 j 位的数值。
fi,s 为只用字符串前 i 位,达到数组和恰为 S 所需要用的最少加号数量。
状态转移方程为:
fi,s=1+j<imin(fj,s−numj+1,i)。
喜提 93pts,WA on#3 求调。