您的位置:首页 > 其它

dp处理大数整除6的最大位数Divide by Six

2017-04-10 17:18 260 查看
                                                    题址:https://oj.ejq.me/problem/24   

 
Divide by Six


Input file: standard input
Output file: standard output Time limit: 1 secondMemory limit: 512 mebibytes

A positive integer number n is written on a blackboard. It consists of not more than 10^510​5​​ digits.
You have to transform it into a mogicalnumber by erasing some of the digits, and you want to erase as few digits as possible.

The number is lucky if it consists of at least one digit, doesn't have leading zeroes and is a multiple of 6. For example, 0, 66,66666 are lucky numbers, and 00, 25, 77 are not.

Write a program which for the given nn will
find a mogical number such that nn can
be transformed into this number by erasing as few digits as possible. You can erase an arbitraty set of digits. For example, they don't have to go one after another in the number nn.

Print the length of your answer after the erasing.

If it's impossible to obtain a lucky number, print 
-1s
.


Input

The first line of input contains nn --
a positive integer ( 1\le
n \le 10^{100000}1≤n≤10​100000​​ ).


Output

Print one number — the number of your lucky number obtained by erasing as few as possible digits. If there is no answer, print 
-1s
.


Example


Input 1

0010456


Output 1

4


Input 2

11


Output 2

-1s

题意:一个小于等于100000位的数字n,(10^100000>=n>=1);在这个数字中选出一些数字(不可改变顺序)组成6的倍数,输出符合条件的最长的位数。
例如样例0010456,选1056符合条件。如果找不到符合条件的则输出-1s;

(下面出现的余数都表示取余6的余数)

思路:首先int dp[100010][6];dp【i】【j】表示前i位(余数为j)的最长的位数;

dp初始化为-1e9;用ans来存最大值,ans初始化也为-1e9。如果数字中有0的话,ans至少是1;

dp【i】【0】一定表示前i位能整除6的最大位数。

因为dp【i】【j】可以由dp【i-1】【k】+1得来。

下面的t表示第i位上的数字。

状态转移方程:dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1);  

附上AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#define LL long long int
#define inf 0x3f3f3f3f
#define N 1000010
using namespace std;
char a[100005];
int dp[100005][7];
int main()
{
while(~scanf("%s",a+1))
{
int n=strlen(a+1);
for(int i=0;i<=n;i++)
for(int j=0;j<6;j++)
dp[i][j]=-inf;
int ans=-inf;
for(int i=1;i<=n;i++)
if(a[i]=='0')
{
ans=1;
break;
}
for(int i=1;i<=n;i++)
{
int t=a[i]-'0';
if(t!=0)
dp[i][t%6]=max(dp[i][t%6],1);
for(int j=0;j<6;j++)
dp[i][j]=max(dp[i-1][j],dp[i][j]);
for(int j=0;j<6;j++)
{
dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1);
}
ans=max(ans,dp[i][0]);
}
if(ans>0)
printf("%d\n",ans);
else
printf("-1s\n");

}
}
比赛后看第一名的代码,才知道原来这题能用dp做。这真是一道好题啊啊啊。

杭电的一道类似题:http://acm.hdu.edu.cn/showproblem.php?pid=6020  都是好题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息