简单dp大合集

poj 1088 - 滑雪(dfs记忆化搜索)

题意:

中文题略

思路:
dp[i][j]表示到达(i,j)点的最长路径长度

代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "string"
#include "cmath"
#include "queue"
#include "cstdio"
#include "algorithm"
#include "cctype"
#include "vector"
#include "map"
#include "stack"
using namespace std;
typedef long long LL;
const int INF = 0x6fffffff;
const int inf = 522133279;
const LL llinf = 1e30;
const double eps = 1e-10;

int g[110][110];
int dir[4][2] = {0,1,1,0,0,-1,-1,0};
int dp[110][110];

int x,y;
int maxc=-1;

int border(int xx , int yy)
{
    return (xx >= 0 && xx < x) && (yy >= 0 && yy < y);
}

int dfs(int m , int n)
{
    if(dp[m][n])            //已经有了最大值记录,避免重复计算
        return dp[m][n];

    int maxn = 0;

    for(int i = 0 ; i < 4 ; i++)
    {
        int tmpx = m+dir[i][0];
        int tmpy = n+dir[i][1];

        if(border(tmpx,tmpy) && g[m][n] > g[tmpx][tmpy])       //获得最大值
            dp[m][n] = max(dp[m][n] , dfs(tmpx,tmpy)+1);
    }

    return dp[m][n];
}

int main()
{
    while(~scanf("%d%d" , &x,&y))
    {
        memset(dp,0,sizeof(dp));

        for(int i = 0 ; i < x ; i++)
            for(int j = 0; j < y ; j++)
                scanf("%d",&g[i][j]);

        for(int i = 0 ; i < x ; i++)
            for(int j = 0; j < y ; j++)
                maxc = max(maxc,dfs(i,j));

        printf("%d\n",maxc+1);
    }

    return 0;
}

hdu 4800 - Josephina and RPG


题意:
有Size = C(3,m)种组合兵种(0开始编号),给出一个Size*Size的矩阵g,g[i][j]表示i组合打赢j组合的概率,如果某一组i打赢了j,i可以换成j的组合继续攻打敌人
给出一组N个组合的序列,问打赢它们的最大概率是多少

思路:
dp[i][j] 表示打败第i个组合之后我方当前队伍为j
order[i]表示第i组敌人的编号

状态转移方程:
dp[i][j] = max(dp[i-1][j]*g[j][order[i]] , dp[i][j]);                              打败i-1的是j组合,仍旧用j去攻打i
dp[i][order[i]] = max(dp[i][order[i]] , dp[i-1][j] * g[j][order[i]]);         打败i-1的是j组合,接下来换成被j打败的order[i]兵种去攻打

代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "string"
#include "cmath"
#include "queue"
#include "cstdio"
#include "algorithm"
#include "cctype"
#include "vector"
#include "map"
#include "stack"
using namespace std;
typedef long long LL;
const int INF = 0x6fffffff;
const int inf = 522133279;
const LL llinf = 1e30;
const double eps = 1e-10;

int M,N;
double g[200][200];
double dp[10010][200];                //dp[i][j] 打败第i个组合之后我方当前队伍为j
int order[10010];

int main()
{
    while(~scanf("%d" , &M))
    {
        memset(dp,0,sizeof(dp));

        int Size = (M-1)*(M-2)*M/6;

        for(int i = 0 ; i < Size ; i++)
            for(int j = 0 ; j < Size ; j++)
                scanf("%lf" , &g[i][j]);

        scanf("%d" , &N);
        for(int i = 1 ; i <= N ; i++)
            scanf("%d" , order+i);

        for(int i = 0 ; i < Size ; i++)
            dp[0][i] = 1;

        for(int i = 1 ; i <= N ; i++)
            for(int j = 0 ; j < Size ; j++)
            {
                dp[i][j] = max(dp[i-1][j]*g[j][order[i]] , dp[i][j]);
                dp[i][order[i]] = max(dp[i][order[i]] , dp[i-1][j] * g[j][order[i]]);
            }

        double maxn = -1;
        for(int i = 0 ; i < Size ; i++)
            maxn = max(maxn,dp[N][i]);

        printf("%.6lf\n" , maxn);
    }

    return 0;
}


hdu 2084 - 数塔(记忆化)

题意:
中文题略

思路:
dfs构造dp方程

代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "string"
#include "cmath"
#include "queue"
#include "cstdio"
#include "algorithm"
#include "cctype"
#include "vector"
#include "map"
#include "stack"
using namespace std;
typedef long long LL;
const int INF = 0x6fffffff;
const int inf = 522133279;
const LL llinf = 1e30;
const double eps = 1e-10;
const int MOD=20121014;

int dp[110][110];
int g[110][110];
int n;

int dfs(int hang,int pos)
{
    if(hang == n)
        return g[hang][pos];

    if(dp[hang][pos])
        return dp[hang][pos];


    return dp[hang][pos] = max(dfs(hang+1,pos), dfs(hang+1,pos+1))+g[hang][pos];
}

int main()
{
    int t;
    scanf("%d",&t);

    while(t--)
    {
        memset(dp,0,sizeof dp);

        scanf("%d",  &n);
        for(int i = 1 ; i <= n ; i++)
            for(int j = 1 ; j <= i ; j++)
                scanf("%d" , &g[i][j]);

        printf("%d\n" , dfs(1,1));
    }

    return 0;
}

hdu 2571 - 命运

题意:
中文题略

思路:
还是记忆化,dfs构造特别清晰

代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "string"
#include "cmath"
#include "queue"
#include "cstdio"
#include "algorithm"
#include "cctype"
#include "vector"
#include "map"
#include "stack"
using namespace std;
typedef long long LL;
const int INF = 0x6fffffff;
const int inf = 522133279;
const LL llinf = 1e30;
const double eps = 1e-10;
const int MOD=20121014;

int m,n;
int g[30][1100];
int dp[30][1100];

int dfs(int x , int y)
{
    if(dp[x][y])
        return dp[x][y];

    if(x == m && y == n)
        return g[m][n];

    int maxc = -inf;

    if(x < m)
        maxc = max(maxc,dfs(x+1,y));
    if(y < n)
        maxc = max(maxc,dfs(x,y+1));

    for(int i = 2 ; i*y <= n ; i++)
        maxc = max(maxc,dfs(x,i*y));

    return dp[x][y] = maxc + g[x][y];
}

int main()
{
    int t;
    scanf("%d" , &t);

    while(t--)
    {
        memset(dp,0,sizeof(dp));

        scanf("%d%d" , &m,&n);

        for(int i = 1 ; i <= m ; i++)
            for(int j = 1 ; j <= n ; j++)
                scanf("%d",&g[i][j]);

        printf("%d\n",dfs(1,1));
    }

    return 0;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值