动态规划专题 - 解题报告

Posted dongdong25800

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划专题 - 解题报告相关的知识,希望对你有一定的参考价值。

 

 https://acm.uestc.edu.cn/contest/15/summary/?tdsourcetag=s_pctim_aiomsg

 

 

A状压DP

注意要开long long

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[1<<18][18];
ll e[20][20];
ll x[20],y[20];
const ll INF=1e18;
int main()

    int n,s;
    scanf("%d%d",&n,&s);
    int tot=0;
    for(int i=1; i<=n; i++)
    
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if(s==i)
        
            x[n-1]=a;
            y[n-1]=b;
        
        else
        
            x[tot]=a;
            y[tot]=b;
            tot++;
        
    
    for(int i=0; i<tot; i++)
        for(int j=0; j<tot; j++)
        
            e[i][j]=abs(x[i]-x[j])+abs(y[i]-y[j]);
        
    for(int s=0;s<(1<<tot);s++)
        for(int i=0;i<tot;i++)
            dp[s][i]=INF;
    for(int i=0;i<tot;i++)
        dp[1<<i][i]=abs(x[i]-x[n-1])+abs(y[i]-y[n-1]);
    for(int s=0;s<(1<<tot);s++)
        for(int i=0;i<tot;i++)
            for(int j=0;j<tot;j++)
            
                if(i!=j&&((1<<i)&s)&&(((1<<j)&s)==0))
                
                    dp[s|1<<j][j]=min(dp[s|1<<j][j],dp[s][i]+e[i][j]);
                
            
    ll ans=INF;
    for(int i=0;i<tot;i++)
    
        ans=min(ans,dp[(1<<tot)-1][i]);
//        printf("%d\n",dp[(1<<tot)-1][i]);
    
    printf("%lld",ans);
View Code

B

日哦,没说矿道不能拐弯?只能直西直北?浪费时间!

技术图片
#include<bits/stdc++.h>
using namespace std;

int a[505][505];
int b[505][505];
int xi[505][505];
int bei[505][505];
int f[505][505];
int main()

    int n,m;
    while(scanf("%d%d",&n,&m)&&n)
    
        memset(f,0,sizeof(f));
        memset(xi,0,sizeof(xi));
        memset(bei,0,sizeof(bei));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
            
                scanf("%d",&a[i][j]);
                xi[i][j]+=xi[i][j-1]+a[i][j];
            
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
            
                scanf("%d",&b[i][j]);
                bei[i][j]+=bei[i-1][j]+b[i][j];
            
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                f[i][j]=max(xi[i][j]+f[i-1][j],bei[i][j]+f[i][j-1]);
        printf("%d\n",f[n][m]);
    
View Code

D

正反求一次到每个数字且末尾数字为该数字的最长上升子序列,然后枚举每个端点作为中间值。注意!初始化box为负无穷,注意数据范围

技术图片
#include<bits/stdc++.h>
using namespace std;

const int maxn=1e6+10;
#define ll long long
int lt[maxn],rt[maxn];
int box[maxn];
int a[maxn];

int main()

    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    int len=0;
    box[0]=-1e9-10;
    for(int i=1; i<=n; i++)
    
        if(a[i]>box[len])
        
            box[++len]=a[i];
            lt[i]=len;
        
        else
        
            int pos=lower_bound(box+1,box+1+len,a[i])-box;
            box[pos]=a[i];
            lt[i]=pos;
        

    
    len=0;
    memset(box,0,sizeof(box));
    box[0]=-1e9-10;
    for(int i=n; i>=1; i--)
    
        if(a[i]>box[len])
        
            box[++len]=a[i];
            rt[i]=len;
        
        else
        
            int pos=lower_bound(box+1,box+1+len,a[i])-box;
            box[pos]=a[i];
            rt[i]=pos;
        
    
    ll ans=0;
    for(int i=1; i<=n; i++)
        ans=max(ans,1ll*min(lt[i],rt[i])*2-1);
    printf("%lld",ans);
View Code

 

以上是关于动态规划专题 - 解题报告的主要内容,如果未能解决你的问题,请参考以下文章

动态规划_leetcode312解题报告

解题报告P1896 [SCOI2005]互不侵犯

动态规划之01背包详解解题报告

2018年暑假ACM个人训练题9(动态规划)解题报告

[Leetcode188] 买卖股票的最佳时机IV 动态规划 解题报告

动态规划高频题汇总 | 今日直播划重点