上次被学长的问题给问住了,突然发现自己动规有点糊涂,然后就去屁颠屁颠的复习,找几个之前做过的题,突然发现,竟然还是写了好久才写出来,怎么说呢,信心被强烈打击到,然后自己找了一个练习题做,不做还好,这一做更加自卑了,呆了半天都没呆出点什么,然后还是看着dalao的题解,然后不断模拟才理解的一题:
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模
输入描述:
输入一个字符串,由数字构成,长度小于等于50
输出描述:
输出一个整数
示例1
输入
复制132
132
输出
复制3
3
示例2
输入
复制9
9
输出
复制1
1
示例3
输入
复制333
333
输出
复制7
7
示例4
输入
复制123456
123456
输出
复制23
23
示例5
输入
复制00
00
输出
复制3
3
备注:
n为长度 子任务1: n <= 5 子任务2: n <= 20 子任务3: 无限制
#include<stdio.h>
#include<string.h>
char a[60];
long long dp[55][4];
int main()
{
scanf("%s",a);
int n=strlen(a);
for(int i=1;i<=n;i++)
{
int m=(a[i-1]-'0')%3;
for(int j=0;j<3;j++)
{
dp[i][j]=dp[i-1][j]+dp[i-1][(j+3-m)%3];
if(j==m)dp[i][j]++;
}
}
const int mode=1e9+7;
long long sum=dp[n][0]%mode;
printf("%lld",sum);
return 0;
}
这个题的思路看起来很简单,但是用代码实现着实难了,还好初中的时候老师教过,能除以三的整数各个位数加起来也都能除以三,所以这个代码就横空出世了,所以只要是这个各个位数加起来能除以三的都可以,这时候还是不太好实现(明天把复杂一点但是好理解的和暴力算献上)其实可以想到,如果我们把取余之后加起来等于三的作为一个子序列就一定可以被三整除,但是怎么样才能将每个数的余数到手呢,这时候我们只需要开一个二维数组,后面那个作为余数,然后按题意计算就可以了,对了,要记得最后的答案对1e9取模哦,在这种dp求数量的题里面,一定要记得开龙龙保命。
案例比较长哈哈:现在上代码(代码很短,但实属不易,一把辛酸泪)更可恨的是,要不要把星星放的这么明显:L
突然开始反思自己最近的状态也太差了,思维也只是停留在脑袋里面,不动手去尝试,写作业效率极低,真的要好好反省一下了。