基础dp专题结题报告

HDU - 1024

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

LL a[1000005];
LL mx[1000005];
LL dp[1000005];
int main()
{
    int m,n;
    while(~scanf("%d%d",&m,&n))
    {
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        memset(dp,0,sizeof(dp));
        memset(mx,0,sizeof(mx));
        LL tmp=-inf;
        for(int i=1;i<=m;i++)
        {
            tmp=-919999999999999999LL;
            for(int j=i;j<=n;j++)
            {
                if(i==j)dp[j]=dp[j-1]+a[j];
                else
                dp[j]=max(dp[j-1],mx[j-1])+a[j];
                mx[j-1]=tmp;
                if(dp[j]>tmp)tmp=dp[j];
            }
        }
        cout<<tmp<<endl;
    }
}
/*
n个数中取出m段,要求m段的和最大。
每新加入一个数,要么自己独立成一段,要么跟前边那一个数
属于同一段。
所以dp[i][j]表示j个数分i段必须取j的最大值。
对于dp[i][j]=max(dp[i][j-1],max(dp[i-1][k])+a[j]) (k->[1,j-1]);
dp[i][j]的值依赖于dp[i][j-1]和dp[i-1][k];
可以用滚动数组。
其实dp[i-1][k]就是上一行1-(j-1)的最大值,我们可以用一个一维数组记录。
既mx数组。
这样dp数组也可以用一维的了。
*/

HDU - 1029 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int sum=0;
        int ans;
        for(int i=1;i<=n;i++)
        {
            int tmp;
            sca(tmp);
            if(sum==0)
            {
                ans=tmp;
                sum++;
            }
            else if(tmp==ans)
            {
                sum++;
            }
            else sum--;
        }
        printf("%d\n",ans);
    }
}
/*
求出现次数为(n+1)/2次的数,n为奇数
1.排序,中中位数。
2.考虑不同数抵消。最后剩下的是要求的数。
*/

HDU - 1069

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

struct node
{
    int x,y,z;
    friend bool operator <(node a,node b)
    {
        if(a.x!=b.x)return a.x<b.x;
        else return a.y<b.y;
    }
}a[100005];
int dp[10005];
int main()
{
    int n;
    int cas=1;
    while(cin>>n&&n)
    {
        int cnt=1;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[cnt].x=x,a[cnt].y=y,a[cnt].z=z,cnt++;
            a[cnt].x=x,a[cnt].y=z,a[cnt].z=y,cnt++;
            a[cnt].x=y,a[cnt].y=x,a[cnt].z=z,cnt++;
            a[cnt].x=y,a[cnt].y=z,a[cnt].z=x,cnt++;
            a[cnt].x=z,a[cnt].y=x,a[cnt].z=y,cnt++;
            a[cnt].x=z,a[cnt].y=y,a[cnt].z=x,cnt++;
        }

        sort(a+1,a+cnt);
        int ans=-199;
        for(int i=1;i<cnt;i++)dp[i]=a[i].z;
        for(int i=1;i<cnt;i++)
        {
            for(int j=1;j<i;j++)
            {
                if(a[j].x<a[i].x&&a[j].y<a[i].y)
                {
                    dp[i]=max(dp[i],dp[j]+a[i].z);
                    ans=max(ans,dp[i]);
                }
            }
        }
        printf("Case %d: maximum height = ",cas++);
        cout<<ans<<endl;
    }
}
/*
给了一维2微的x和y,一个高度
要求x和y都是严格递减的,求最大高度。其中每种方块都有无限个。
每个方块通过旋转最多产生6种方块。
对一维排序,对另一维求一个最长下降子序列。
如果要求每种块的最大高度就是cdq分治了。
*/

HDU - 1074 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
#define pb(x) push_back(x)
#define sca(x) scanf("%d",&x)
#define inf 0x3f3f3f3f
#define LL long long

string str[20];
int dead[20],cost[20];
int dp[1<<16];
int T[1<<16];
int pre[1<<16],name[1<<16];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        sca(n);
        memset(dp,inf,sizeof(dp));
        memset(T,0,sizeof(T));
        for(int i=0;i<n;i++)
        {
            cin>>str[i]>>dead[i]>>cost[i];
        }
        int bit=1<<n;
        T[0]=0;
        dp[0]=0;
        for(int i=1;i<bit;i++)
        {
            for(int j=n;j>=0;j--)
            {
                int tmp=1<<j;
                if(!(i&tmp))continue;
                int tmp1=i^tmp;
                int red=max(T[tmp1]+cost[j]-dead[j],0);
                int v=dp[tmp1]+red;
                //cout<<i<<" "<<j<<" "<<v<<endl;
                if(v<dp
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值