字符串切开后每段的数字和都尽可能被7整除。
输入:一个字符串s,s的每位都是数字
输出:输出一个整数,表示切开后最多能有多少段的数字和是7的倍数。
例:s为12457,可以切分为124|5|7,第一段和第三段的和能被7整除,输出2
dp[i]:表示到i位置为止,最多有多少段的数字和是7的倍数。
dp[i]需要比较的点:要包含i的段,or不要包含i的段
string str;
int len = str.size();
int dp[len];
dp[0] = (str[0] == '0' || str[0] == '7') ? 1 : 0;
int cnt_max = dp[0];
for (int i = 1; i < len; i++) {
if (str[i] == '0' || str[i] == '7') {
dp[i] = cnt_max + 1;
cnt_max += 1;
} else {
int sum = str[i] - '0';
int j = i - 1;
for (; j >= 0; j--) {
sum += str[j] - '0';
if (sum % 7 == 0) {
break;
}
}
if (j > 0) {
dp[i] = max(cnt_max, dp[j - 1] + 1);
} else if (sum % 7 == 0) {
dp[i] = max(cnt_max, 1);
} else {
dp[i] = cnt_max;
}
cnt_max = max(cnt_max, dp[i]);
}
}
完全背包
给整数数组 coins
,表示不同面额的硬币;以及一个整数 amount
,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数
dp[i]: 总金额为i时最少的硬币个数
双循环:对于每一个总金额i,遍历所有硬币,比较min(dp[i - coins[j]])
注意点:初始需要把dp都初始化为max,表示dp[i]不能用硬币刚好凑到
int dp[amount + 1];
fill(dp, dp+amount+1, 1000000007);
dp[0] = 0;
int len = coins.size();
for (int i = 1; i <= amount; i++) {
for (int j = 0; j < len; j++) {
if (i - coins[j] >= 0 && dp[i - coins[j]] != 1000000007) {
dp[i] = min(dp[i], dp[i - coins[j]]+1);
}
}
}
if (dp[amount] == 1000000007) {
return -1;
} else {
return dp[amount];
}