修炼dp( 2 )

P1084 数字三角形4

题解:dp+dfs.

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 40;
int dp[maxn][maxn];
int cnt[maxn][maxn];
int n;
int dfs(int x,int y)
{
    if(x==1&&y==1) return cnt[1][1];
    if(y==1) return dfs(x-1,y)+cnt[x][y];
    if(x>1)return max(dfs(x-1,y),dfs(x-1,y-1))+cnt[x][y];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            scanf("%d",&cnt[i][j]);
        }
    }
    int x,y;
    scanf("%d %d",&x,&y);
    for(int i=1;i<=n;i++) dp[n][i] = cnt[n][i];
    for(int i=n-1;i>=x;i--)
    {
        for(int j=1;j<=i;j++)
        {
            dp[i][j] = max(dp[i+1][j],dp[i+1][j+1])+cnt[i][j];
        }
    }
    int sum = 0;
    sum = dfs(x,y);
    sum = sum+dp[x][y]-cnt[x][y];
    printf("%d\n",sum);
    return 0;
}
/*
4
7
1 2
3 4 5
7 3 8 9
3 2
*/
卷珠帘

 

P1004 滑雪

题解:dfs.咦,我本来是来炼dp的。。。不做水题了。

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m;
const int maxn = 105;
int cnt[maxn][maxn];
int vis[maxn][maxn];
int dp[maxn][maxn];
int dfs(int x,int y)
{
    if(x<1||y<1) return 0;
    if(x>n||y>m) return 0;
    if(vis[x][y]) return dp[x][y];
    vis[x][y] = 1;
    int a,b,c,d;
    a = b = c = d = 0;
    if(cnt[x-1][y]<cnt[x][y]) a = dfs(x-1,y);
    if(cnt[x+1][y]<cnt[x][y]) b = dfs(x+1,y);
    if(cnt[x][y+1]<cnt[x][y]) c = dfs(x,y+1);
    if(cnt[x][y-1]<cnt[x][y]) d = dfs(x,y-1);
    dp[x][y] = max(max(a,b),max(c,d))+1;
    return dp[x][y];
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&cnt[i][j]);
        }
    }
    int maxx = 0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            maxx = max(dfs(i,j),maxx);
        }
    }
    printf("%d\n",maxx);
}
卷珠帘

 

nyoj15 括号匹配(二)

题解:接触的第一道区间dp题。

 
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 111;
char s[maxn];
int dp[maxn][maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s+1);
        int n = strlen(s+1);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i == j) dp[i][j] = 1;
                else dp[i][j] = 1000;
            }
            dp[i][i-1] = 0;
        }
        //i和j分别表示一段连续字符的起点和终点
        for(int l=1;l<=n-1;l++)
        {
            for(int i=1;i+l<=n;i++)
            {
                int j = i+l;
                if(s[i]=='('&&s[j]==')'||(s[i]=='['&&s[j]==']')) dp[i][j] = min(dp[i][j],dp[i+1][j-1]);
                for(int k=i;k<j;k++)
                {
                    dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
                }
            }
        }
        printf("%d\n",dp[1][n]);
    }
}

/*
31
()([)][])
*/
        
卷珠帘

 

posted @ 2016-07-28 17:19  卷珠帘  阅读(134)  评论(0编辑  收藏  举报