码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces2B--动态规划(路径DP)

时间:2014-09-07 18:28:15      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   io   ar   for   div   sp   

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <algorithm>

typedef short int int16;///32767
typedef int int32;///2147483647
typedef long long int64;///9223372036854775807
const double PI=acos(-1.0);///3.141593
const long long MOD=(long long)1E9+7LL;///1000000007
template <class T> T Susake_pow(T a,T b)///pow
{T res;if(b==0) return 1;else while((b&1)==0){b>>=1;a*=a;}res=a;b>>=1;while(b!=0){a*=a;if((b&1)!=0)res*=a;b>>=1;}return res;}
template<class T> inline T gcd(T a,T b)///gcd
{if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template<class T> inline T lcm(T a,T b)///lcm
{if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template<class T> inline char *Susake_nsystem(T n)///itoa(26)
{T t=0,i;char *s,*p;s=(char *)malloc(sizeof(char)*1000);p=(char *)malloc(sizeof(char)*1000);
while(n){s[t]=n%26+64;if(s[t]==64){s[t]+=26;n-=26;}t++;n/=26;}s[t]=\0;for(i = 0; i < t; i++)p[i]=s[t-1-i];p[i]=\0;free(s);return p;}
int Susake_msystem(char *s)///atoi(26)
{int len=strlen(s),i,sum=0;char p[1000];for(i=0;i<len;i++)p[i]=s[len-1-i]-64;for(i=0;i<len;i++)sum+=p[i]*Susake_pow(26,i);return sum;}

int a[1003][1003];
char path[2003];

void judge(int &x2, int &x5, int n)
{
    x2 = x5 = 0;
    while(n % 5 == 0 && n)
    {
        n /= 5;
        x5++;
    }
    while(n % 2 == 0 && n)
    {
        n /= 2;
        x2++;
    }
}

struct Node
{
    int Susake2;
    int Susake5;
    int px, py;
};

Node Susake[1003][1003], dp1[1003][1003], dp2[1003][1003];

int main(int argc, char *argv[])
{
    int n, x2, x5, Min1, Min2, k1, k2, flag, ex, ey, tx, ty, si, sj, God;
    memset(a, 0, sizeof(a));
    memset(Susake, 0, sizeof(Susake));
    memset(path, 0, sizeof(path));
    scanf("%d", &n);
    flag = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            scanf("%d", &a[i][j]);
            if(a[i][j] == 0 && flag == 0)
            {
                flag = 1;
                si = i;
                sj = j;
            }
            judge(x2, x5, a[i][j]);
            Susake[i][j].Susake2 = x2;
            Susake[i][j].Susake5 = x5;
        }
    //bround
    dp1[0][0].Susake2 = 0;
    dp1[1][0].Susake2 = 0;
    dp1[0][1].Susake2 = 0;
    dp2[0][0].Susake5 = 0;
    dp2[1][0].Susake5 = 0;
    dp2[0][1].Susake5 = 0;
    for(int i = 2; i <= n; i++)
    {
        dp1[i][0].Susake2 = 1000000009;
        dp1[0][i].Susake2 = 1000000009;
        dp2[i][0].Susake5 = 1000000009;
        dp2[0][i].Susake5 = 1000000009;
    }
    //according to 2 dp
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            dp1[i][j].Susake2 = std::min(dp1[i - 1][j].Susake2, dp1[i][j - 1].Susake2) + Susake[i][j].Susake2;
            //Save path
            if(dp1[i - 1][j].Susake2 < dp1[i][j - 1].Susake2)
            {
                dp1[i][j].px = i - 1;
                dp1[i][j].py = j;
            }
            if(dp1[i - 1][j].Susake2 >= dp1[i][j - 1].Susake2)
            {
                dp1[i][j].px = i;
                dp1[i][j].py = j - 1;
            }
        }
    Min1 = dp1[n][n].Susake2;
    //according to 5 dp
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            dp2[i][j].Susake5 = std::min(dp2[i - 1][j].Susake5, dp2[i][j - 1].Susake5) + Susake[i][j].Susake5;
            //Save path
            if(dp2[i - 1][j].Susake5 < dp2[i][j - 1].Susake5)
            {
                dp2[i][j].px = i - 1;
                dp2[i][j].py = j;
            }
            if(dp2[i - 1][j].Susake5 >= dp2[i][j - 1].Susake5)
            {
                dp2[i][j].px = i;
                dp2[i][j].py = j - 1;
            }
        }
    Min2 = dp2[n][n].Susake5;
    //print the path
    dp1[1][1].px = 1;
    dp1[1][1].py = 1;
    dp2[1][1].px = 1;
    dp2[1][1].py = 1;
    God = 0;
    if(std::min(Min1, Min2) > 1 && flag)
    {
        printf("%d\n", 1);
        for(int i = 2; i <= si; i++)
            printf("D");
        for(int i = 2; i <= sj; i++)
            printf("R");
        for(int i = si + 1; i <= n; i++)
            printf("D");
        for(int i = sj + 1; i <= n; i++)
            printf("R");
        printf("\n");
    }
    else
    {
        if(Min1 <= Min2)
        {
            k1 = 0;
            tx = ty = n;
            ex = tx; ey = ty;
            tx = dp1[tx][ty].px;
            ty = dp1[tx][ty].py;
            if(a[ex][ey] == 0)
                God = 1;
            if(a[tx][ty] == 0)
                God = 1;
            if(tx < ex)
            {
                k1++;
                path[k1] = D;
            }
            if(ty < ey)
            {
                k1++;
                path[k1] = R;
            }
            ex = tx; ey = ty;
            while(tx != 1 || ty != 1)
            {
                tx = dp1[ex][ey].px;
                ty = dp1[ex][ey].py;
                if(a[tx][ty] == 0)
                God = 1;
                if(tx < ex)
                {
                    k1++;
                    path[k1] = D;
                }
                if(ty < ey)
                {
                    k1++;
                    path[k1] = R;
                }
                ex = tx; ey = ty;
            }
            if(God == 1)
                printf("1\n");
            else
                printf("%d\n", std::min(Min1, Min2));
            for(int i = k1; i >= 1; i--)
                printf("%c", path[i]);
            printf("\n");
        }
        else
        {
            k2 = 0;
            tx = ty = n;
            ex = tx; ey = ty;
            tx = dp2[tx][ty].px;
            ty = dp2[tx][ty].py;
            if(a[ex][ey] == 0)
                God = 1;
            if(a[tx][ty] == 0)
                God = 1;
            if(tx < ex)
            {
                k2++;
                path[k2] = D;
            }
            if(ty < ey)
            {
                k2++;
                path[k2] = R;
            }
            ex = tx; ey = ty;
            while(tx != 1 || ty != 1)
            {
                tx = dp2[ex][ey].px;
                ty = dp2[ex][ey].py;
                if(a[tx][ty] == 0)
                God = 1;
                if(tx < ex)
                {
                    k2++;
                    path[k2] = D;
                }
                if(ty < ey)
                {
                    k2++;
                    path[k2] = R;
                }
                ex = tx; ey = ty;
            }
            if(God == 1)
                printf("1\n");
            else
                printf("%d\n", std::min(Min1, Min2));
            for(int i = k2; i >= 1; i--)
                printf("%c", path[i]);
            printf("\n");
        }
    }
    return 0;
}

 

Codeforces2B--动态规划(路径DP)

标签:style   blog   color   os   io   ar   for   div   sp   

原文地址:http://www.cnblogs.com/Susake/p/3960562.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!