HDU5092

来源:互联网 发布:mac视网膜壁纸 编辑:程序博客网 时间:2024/05/19 04:54

这道题呢,原型就应该是数塔,是一个比较基础的动态规划 + 回溯路径,还有一点,这个题意,我最开始竟然没有读懂,实际就是找到一条权值和从上到下最短的。

#include<iostream>

#include<cstdio>
#include<string.h>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<sstream>
#include<queue>


#define ll __int64
#define lll unsigned long long
#define MAX 1000009
#define MAXN 2009
#define eps 1e-8
#define INF 0x7fffffff
#define mod 1000000007
#define clr(a) memset(a,0,sizeof(a))
#define clr1(a) memset(a,-1,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1


using namespace std;


inline ll Max(ll a,ll b)
{
    return a>b?a:b;
}
inline ll Min(ll a,ll b)
{
    return a<b?a:b;
}


int dp[109][109];
int a[109][109];
int path[109][109];
int ans[109];


void print(int num,int index)
{
    if(num<1)return ;
    if(path[num][index]==-1)
    {
        printf("%d",index);
        return ;
    }
    else
    {
        print(num-1,path[num][index]);
        printf(" %d",index);
    }
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("ans.txt","r", stdin);
    //freopen("out.txt","r", stdout);
#endif
    int T;
    int d = 1;
    int m,n;
    scanf("%d",&T);
    while(T--)
    {
        clr(a);
        clr1(path);
        scanf("%d%d",&n,&m);
        for(int i = 0; i<109; i++)
            for(int j = 0; j<109; j++)
                dp[i][j] = MAX;
        for(int i = 1; i<=n; i++)
            for(int j = 1; j<=m; j++)
                scanf("%d",&a[i][j]);


        for(int i = 1; i<=m; i++) dp[1][i] = a[1][i];
        for(int i = 2; i<=n; i++)
        {
            for(int j = 1; j<=m; j++)
            {
                if(j!=1&&dp[i][j] > dp[i - 1][j - 1] + a[i][j])
                {
                    dp[i][j] = dp[i - 1][j - 1] + a[i][j];
                    path[i][j] = j - 1;
                }
                if(dp[i][j] >= dp[i - 1][j] + a[i][j])
                {
                    dp[i][j] = dp[i - 1][j] + a[i][j];
                    path[i][j] = j;
                }
                if(j!=m&&dp[i][j] >= dp[i - 1][j + 1] + a[i][j])
                {
                    dp[i][j] = dp[i - 1][j + 1] + a[i][j];
                    path[i][j] = j + 1;
                }
            }
        }
        int index = -1;
        int _min = INF;
        for(int i = m; i>=1; i--)
        {
            if(_min > dp[n][i])
            {
                _min = dp[n][i];
                index = i;
            }
        }
        printf("Case %d\n",d++);
        print(n,index);
        puts("");
    }
    return 0;
}
0 0
原创粉丝点击