zoukankan      html  css  js  c++  java
  • hdu 4433 locker 夜

    http://acm.hdu.edu.cn/showproblem.php?pid=4433

    记忆化搜索+DP

    ans[x][f][ff]; 表示到a的第x位时 此位加f ,x-1位 加ff 的情况下的最优解

    a的x位加f后如果还不到 b[x] 然后分两种情况 一个是a的第x位不断加 直到等于b[x] 或者不断减直到等于b[x]

    对于两种情况 分别枚举长度为 1 ,2 ,3的个数的情况  对下两层的影响 对下两层的影响 无论是加多少还是减多少 都可以转化为 加上一个10以内的数(因为是循环的)

    然后不断递归

    时间复杂度 O(N*10*10*C(12,2))  大约10^7

    代码及其注释:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<queue>
    #include<map>
    #include<string>
    #include <iomanip>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int N=1005;
    int ans[N][12][12];//到第x位时 此位加f ,x-1位 加ff 时的最优解
    char s1[N],s2[N];
    int a[N],b[N];
    int dp(int x,int f,int ff)
    {
        if(ans[x][f][ff]!=-1)
        return ans[x][f][ff];
        int tmp=(a[x]+f)%10;//x位加 f 后的结果
        if(x==0)
        {
            if(ff!=0)//到第0位时 -1位不能再进行加减
            return (ans[x][f][ff]=INF);
            return (ans[x][f][ff]=min((b[x]-tmp+10)%10,(tmp-b[x]+10)%10));//否则选个最优就可
        }
        if(tmp==b[x])//当前位已经不需要加减
        return (ans[x][f][ff]=dp(x-1,ff,0));
        ans[x][f][ff]=INF;
        int k=(b[x]-tmp+10)%10;//不断加的情况
        for(int i=0;i<=k;++i)
        for(int j=0;j<=(k-i);++j)
        {
            int l=k-i-j;
            if(i+j+l==k)//枚举 长度1,2,3的个数的情况 对下两层的影响 求最优解
            ans[x][f][ff]=min(ans[x][f][ff],k+dp(x-1,(ff+i+l)%10,l));
        }
        k=(tmp-b[x]+10)%10;//不断减的情况
        for(int i=0;i<=k;++i)
        for(int j=0;j<=(k-i);++j)
        {
            int l=k-i-j;
            if(i+j+l==k)
            ans[x][f][ff]=min(ans[x][f][ff],k+dp(x-1,(ff-i-l+10)%10,(-l+10)%10));
        }
        return ans[x][f][ff];
    }
    int main()
    {
        //freopen("data.txt","r",stdin);
        while(scanf("%s %s",s1,s2)!=EOF)
        {
            memset(ans,-1,sizeof(ans));
            int n=strlen(s1);
            for(int i=0;i<n;++i)
            {a[i]=s1[i]-'0';b[i]=s2[i]-'0';}
            printf("%d\n",dp(n-1,0,0));
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    shell 函数
    PHP curl 实现RESTful PUT DELETE 实例
    call_user_func_array
    Laravel 文档中的 Service Providers
    window7主题破解与恢复(复制)
    ORM到底是用还是不用?(复制)
    关于cgi、FastCGI、php-fpm、php-cgi(复制)
    C语言赋初始值
    MySQL临时表的简单用法(复制)
    Mysql Having的用法:对group by之后的分组加限制条件(复制)
  • 原文地址:https://www.cnblogs.com/liulangye/p/2746966.html
Copyright © 2011-2022 走看看