推荐系列:最小与最大[DP+余式定理]

 最小与最大

【问题描述】

做过了乘积最大这道题,相信这道题也难不倒你。

已知一个数串,可以在适当的位置加入乘号(设加了k个,当然也可不加,即分成k+1个部分),设这k+1个部分的乘积(如果k=0,则乘积即为原数串的值)对m 的余数(即mod m)为x;

现求x能达到的最小值及该情况下k的最小值,以及x能达到的最大值及该情况下的k的最小值(可以存在x的最小值与最大值相同的情况)。

【输入】

第一行为数串,长度为n 满足2<=n<=1000,且数串中不存在0;

第二行为m,满足2<=m<=50。

【输出】

四个数,分别为x的最小值 和 该情况下的k,以及x的最大值和 该情况下的k,中间用空格隔开。

【样例输入】

4421

22

【样例输出】

0 1 21 0

 

 

 

感觉这题挺好的。

首先你需要知道余式定理: (a*b)mod m = ((a mod m)*(b mod m ))mod m

令f[i][j]表示,前i个数,余数为j时用的k

b[i][j]表示,第i个数到第j个数所形成的数mod m 的值

 

f[k][s] = min{f[i][j]+1}

其中s=(b[i+1][k]*j)mod m;(余式定理)

怎么理解这个状态转移方程呢?理解各自表示的涵义即可。

b[i+1][k]为,第i+1个数到第k个数所形成的数mod m的值

f[k][s]表示前k个数,余数为s时用的k。状态转移方程即可理解。

 

输出结果的时候,

因为f中已经存下来能达到所有余数的最少乘号数,所以要输出最大余数,只需要倒着扫一遍,输出最小数只需要顺着扫一遍即可。

原文地址:https://www.cnblogs.com/polebug/p/4066955.html