有关删除数字的dp问题

来源:互联网 发布:外立面效果图制作软件 编辑:程序博客网 时间:2024/06/02 10:52

题意:给定一个数字(100000位)求删除最少的数字使其%6为0(不能有前导0);
Input 1

0010456

Output 1

4

Input 2

11

Output 2

-1s

#include<cstdio>#include<cstring>#include<vector>#include<iostream>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;int dp[100010][10];//dp[i][j]代表前i位余数为j时最少需要删除的数字个数void solve(string s){    memset(dp,0x3f,sizeof(dp));    int len=s.size();    for(int i=0; i<len; i++)    {        if(s[i]!='0')//预处理当前数字不为0时        {            int tmp=(s[i]-'0')%6;            dp[i+1][tmp]=i;//删除前面的所有数使得余数为tmp        }        for(int j=0; j<6; j++)//枚举余数        {            dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1);//当前余j取前一位余j的长度,删掉当前位(前一位余j的长度加一);            int tmp=(j*10+s[i]-'0')%6;//前一位余j到当前位就会余tmp            dp[i+1][tmp]=min(dp[i+1][tmp],dp[i][j]);//取前一位余j余当前位余tmp的最小值        }    }}int main(){    string s;    while(cin>>s)    {        solve(s);        int len=s.size();        int ans=inf;        for(int i=0; i<len; i++)//如果有0课删除len-1位            if(s[i]=='0')            {                ans=len-1;                break;            }            ans=min(ans,dp[len][0]);            if(ans==inf)                printf("-1s\n");            else            printf("%d\n",len-ans);    }}
0 0