• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
2014>
博客园    首页    新随笔    联系   管理    订阅  订阅
dp 入门

1.HDU 1003

求最长连续相加的和。

dp[i]=max(a[i],dp[i-1]+a[i]);

dp[i]表示以 i 结尾的最大值。

再开/个strat去标记从哪里开始。

#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[100010];
int strat[100010];
int a[100010];
int main()
{
   int t;
   scanf("%d",&t);
   int k=0;
   while(t--)
   {
       k++;
       int n;
       scanf("%d",&n);
       for(int i=0;i<n;i++)
       {
           scanf("%d",&a[i]);
       }
       memset(dp,0,sizeof dp);
       memset(strat,0,sizeof dp);
       dp[0]=a[0];
       strat[0]=0;
       int max=a[0];
       int pp=0;
       for(int i=1;i<n;i++)
       {
           if(a[i]>a[i]+dp[i-1])
           {
             dp[i]=a[i];
             strat[i]=i;
           }
           else
           {
               dp[i]=dp[i-1]+a[i];
               strat[i]=strat[i-1];
           }
           if(max<dp[i])
           {
              max=dp[i];
              pp=i;
           }

       }
       printf("Case %d:\n",k);
       printf("%d %d %d\n",max,strat[pp]+1,pp+1);
        if(t) printf("\n");




   }
    return 0;
}

 2.hdu 1087

求最长上升序列的和;

dp[i]=max(dp[j])+a[i];   a[j]<a[i];  

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1005];
int a[1005];
int main()
{
   int n;
   while(~scanf("%d",&n))
   {
       if(n==0)
        break;
       for(int i=0;i<n;i++)
       {
           scanf("%d",&a[i]);
       }
       memset(dp,0,sizeof dp);
        dp[0]=a[0];
       for(int i=1;i<n;i++)
       {
            int MAX=0;
          for(int j=0;j<i;j++)
          {
             
            if(a[i]>a[j])
            {
                MAX=max(MAX,dp[j]);
            }
          }
         dp[i]=MAX+a[i];
       }
       int t=0;
       for(int i=0;i<n;i++)
       {
           t=max(t,dp[i]);
       }
       cout<<t<<endl;

   }
    return 0;
}

 

3.HDU 1159  最长公共子序列

dp[i][j]=dp[i-1][j-1]+1   a[i]==b[j]

dp[i][j]=max(dp[i][j-1],dp[i-1][j]);

读入是0 开始。计数的时候 从1开始。

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1005][1005];
char a[1005];
char b[1005];
int main()
{
    while(cin>>a>>b)
    {
        int t1=strlen(a);
        int t2=strlen(b);
        memset(dp,0,sizeof dp);
        for(int i=1;i<=t1;i++)
        for(int j=1;j<=t2;j++)
        {

            if(a[i-1]==b[j-1])
            dp[i][j]=dp[i-1][j-1]+1;
            else
            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

        }
      cout<<dp[t1][t2]<<endl;
}

    return 0;
}

 4.hdu-1160

最长上升子序列加路径

DP[i]表示i结尾的最长数目;

自己加一个 0 0break 测试一下

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
struct node
{
    int w;
    int v;
    int no;
}mice[1000];
bool cmp(node a,node b)
{
      if(a.w==b.w)
    return a.v<b.v;//最开始这里没有排一直出来5。因为体重一样的速度也在排。但是速度从小到大就不会被记录
    return a.w<b.w;
}
int pre[1000];
int dp[1000];
int main()
{
    int a,b;
    int k=0;
    while(cin>>a>>b)
    {
         mice[k].w=a;
         mice[k].v=b;
         mice[k].no=k+1;
         k++;
    }
    sort(mice,mice+k,cmp);
    memset(pre,-1,sizeof pre);
   for(int i=0;i<k;i++)
   {
    dp[i]=1;
   }
    int mx=0,p=-1;
   for(int i = 0; i < k; i++)
    {

    for(int j = 0; j < i; j++)
    {
             if( mice[j].v > mice[i].v)
             {
                if(dp[j]+1 > dp[i])
                {
                    dp[i] = dp[j]+1;
                       pre[i] = j;
                 }
             }
    }

        if(dp[i]>mx)
        {
            mx=dp[i];
            p=i;
        }

    }
    cout<<mx<<endl;
    int res[10000];
    int i=1;
    while(p!=-1)
    {
    res[i++]=mice[p].no;
    p=pre[p];
    }
    i--;
     for(;i>=1;i--)
        cout<<res[i]<<endl;

    return 0;
}

 5.hdu-1176

这题详细写了。

dp[0][i]= dp[0][i]+max(dp[0][i+1],dp[1][i+1]);
dp[j][i]=dp[j][i]+max(dp[j-1][i+1],max(dp[j][i+1],dp[j+1][i+1]));
dp[10][i]= dp[10][i]+max(dp[10][i+1],dp[9][i+1]);
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[11][100005];//i表示时间,j表示位子
int main()
{
    int n;
    int t,p;
    while(~scanf("%d",&n)&&n)
    {
        int mx=0;
       memset(dp,0,sizeof dp);
       for(int i=0;i<n;i++)
       {
         scanf("%d%d",&p,&t);
         dp[p][t]++;
         mx=max(mx,t);
       }
       for(int i=mx-1;i>=0;i--)
       {
           dp[0][i]= dp[0][i]+max(dp[0][i+1],dp[1][i+1]);
           for(int j=1;j<10;j++)
           {
               dp[j][i]=dp[j][i]+max(dp[j-1][i+1],max(dp[j][i+1],dp[j+1][i+1]));
           }
           dp[10][i]= dp[10][i]+max(dp[10][i+1],dp[9][i+1]);
       }
     cout<<dp[5][0]<<endl;


    }
    return 0;
}

 

posted on 2017-08-05 10:31  2014>  阅读(127)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3