zoukankan      html  css  js  c++  java
  • HDU 4433 locker 2012 Asia Tianjin Regional Contest 减少国家DP

    意甲冠军:给定的长度可达1000数的顺序,图像password像锁。可以上下滑动,同时会0-9周期。

    每个操作。最多三个数字连续操作。现在给出的起始序列和靶序列,获得操作的最小数量,从起始序列与靶序列。


    花了一天的时间。我觉得是道非常难的DP。这个阶段非常好划分,对于前面完毕的password锁就不再考虑。问题的关键是这个旋转每次能够的情况非常多。

    同一时候也能够发现当I位置上确定移好后,至多影响到后两位。-> dp[i][j][k] 表示当前i位移好后,i+1 为j ,  i+2为k 的次数。

    这里同一时候使用一个预处理技巧,对于一个移动操作。有向上向下两种。

    当将一个值转到还有一个值,up[i][j]=(j-i+10)%10;down[i][j]=(i-j+10)%10;  i->j 的方法

    在dp中必定会有对于阶段的描写叙述,一般从1開始,表达每一段。这里为了求dp[n][0][0] 在最后再补上两位。

    dp[0][s[0]][s[1]]=0;
    刚開始0阶段,一个都未完毕的时候。即前0次移好i+1,i+2位为这种次数为0

    int r=up[j][t[i-1]];//①
    dp[i][(k+u)%10][(s[i+1]+v)%10]=min(...)//②

    
    这两句话是我刚開始一直困惑的地方。

    首先要明白转移方程是阶段间的转移dp[i-1][...][...]->dp[i][...][...]

    这样看,配合②我们发现当dp[i-1][j][k]已知,dp[i][...][...]是将其  j转为t[i-1]。(这个是理解的关键)。这里的u,v表明的是在j转为t[i-1]过程中。后两位的改变情况枚举值。

    dp[i][(k+u)%10][(s[i+1]+v)%10] 这个如今就能够理解了,对于dp[i-1]的j 如今dp[i]考虑的就是上次的K了。

    另一点就是标号非常乱一会是阶段的i。一会又是起始位置.......

    #include <stdio.h>
    #include <string.h>
    #include <map>
    #include <iostream>
    #define inf 0x3fffffff
    const int maxn=1010;
    typedef unsigned __int64 ull;
    using namespace std;
    char s[maxn],t[maxn];
    int dp[maxn][10][10];
    int up[10][10],down[10][10];
    int min(int a,int b)
    {
    	return a<b?a:b;
    }
    void init()
    {
    	int i,j;
    	for(i=0;i<10;i++)
    		for(j=0;j<10;j++)
    		{
    			up[i][j]=(j-i+10)%10;
    			down[i][j]=(i-j+10)%10;
    		}
    }
    
    int main()
    {
    	init();
    	while(~scanf("%s%s",s,t))
    	{
    		memset(dp,0x3f,sizeof(dp));
    		int i,j,k,u,v;
    		int n=strlen(s);
    		s[n]=s[n+1]=t[n]=t[n+1]=0;
    		for(i=0;i<n;i++)
    			s[i]-='0',t[i]-='0';
    		dp[0][s[0]][s[1]]=0;//除了最初的序列。其它的dp都没有合法值
    		for(i=1;i<=n;i++)
    		{
    			for(j=0;j<10;j++)//枚举两位数字的每一位  
    			{
    				for(k=0;k<10;k++)
    				{
    					int r=up[j][t[i-1]];//从j转到t[i-1]的次数,将三位中最左边的数字向上转到目标序列须要的操作
    					for(u=0;u<=r;u++)//枚举可能出现的操作
    					{
    						for(v=0;v<=u;v++)
    							dp[i][(k+u)%10][(s[i+1]+v)%10]=min(dp[i][(k + u) % 10][(s[i+1] + v) % 10], dp[i-1][j][k] + r);  
    					}
    					r=down[j][t[i-1]];
    					for(u=0;u<=r;u++)
    						for(v=0;v<=u;v++)
    							dp[i][(k-u+10)%10][(s[i+1]-v+10)%10]=min(dp[i][(k - u+10) % 10][(s[i+1] - v +10) % 10], dp[i-1][j][k] + r);
    				}
    			}
    		}
    		printf("%d
    ",dp[n][0][0]);
    	}
    
    
    
    
    	return 0;
    }


  • 相关阅读:
    jQuery $.each用法
    CodeFirst数据库迁移小记
    IOS中input与fixed同时存在的情况会出现bug
    机器学习十讲--第三讲-分类
    机器学习十讲--第二讲-回归
    机器学习十讲--第一讲
    Pandas数据分析
    Tensorflow-各种优化器总结与比较
    TensorFlow版本问题汇总
    深度学习06
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4601594.html
Copyright © 2011-2022 走看看