hdu4433 locker(dp)

4223 ワード

hdu4433
タイトル
2つの列を与える、連続する1~3個の数字を選択し、同時に1を加えるか同時に1を減らすことができ、少なくとも何回の操作を経て、1つの列を別の列に変えることができるかを問う.
構想
dp[i][j][k]は、前のi個が完全に一致していることを示しているが、このとき、i+1個目がj位、i+2位がk位となっており、移行は2ステップに分かれており、列挙が加算され、列挙が減少しているが、あまり受け入れられないような気がする.http://blog.csdn.net/acm_cxlove/article/details/8124726
コード#コード#
#include 
#include 
#include 
#include 

using namespace std;

const int maxn=1000+10;
const int inf=0x3f3f3f3f;

int dp[maxn][10][10];
char s1[maxn],s2[maxn];

int main()
{
    while(scanf("%s %s",s1,s2)!=EOF)
    {
        int len=strlen(s1);
        memset(dp,0x3f,sizeof(dp));
        dp[0][0][0]=0;
        for(int i=0; ifor(int j=0; j<10; j++)
                for(int k=0; k<10; k++)
                {
                    if(dp[i][j][k]!=inf)
                    {
                        int t=(s2[i]-s1[i]-j+20)%10;
                        for(int a=0; a<=t; a++)
                            for(int b=0; b<=a; b++)
                                dp[i+1][(k+a)%10][b]=min(dp[i+1][(k+a)%10][b],dp[i][j][k]+t);
                        t=(10-t)%10;
                        for(int a=0; a<=t; a++)
                            for(int b=0; b<=a; b++)
                                dp[i+1][(k-a+10)%10][(10-b)%10]=min(dp[i+1][(k-a+10)%10][(10-b)%10],dp[i][j][k]+t);
                    }
                }
        printf("%d
"
,dp[len][0][0]); } return 0; }