码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划专题 - 解题报告

时间:2019-07-26 01:35:32      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:while   org   source   pen   ref   open   动态   bsp   adc   

 

 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

 

动态规划专题 - 解题报告

标签:while   org   source   pen   ref   open   动态   bsp   adc   

原文地址:https://www.cnblogs.com/dongdong25800/p/11145088.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!