动态规划专题 - 解题报告

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);
}

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]);
    }
}

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);
}

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

时间: 2024-10-10 09:35:20

动态规划专题 - 解题报告的相关文章

2014 UESTC暑前集训数据结构专题解题报告

A.Islands 这种联通块的问题一看就知道是并查集的思想. 做法:从高水位到低水位依序进行操作,这样每次都有新的块浮出水面,可以在前面的基础上进行合并集合的操作.给每个位置分配一个数字,方便合并集合.同时将这些数字也排一个序,降低枚举的复杂度.合并集合时向四周查询浮出水面但是没有合并到同一集合的点进行合并. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath&

动态规划_leetcode312解题报告

#coding=utf-8 # leetcode 312 解题报告 20190307 找工作期间#解题思路# 假设初始气球的状态是 [3,1,5,8] #.顺向思维# 第一步有四个选择:3,1,5,8 ,# 第二步有三个选择:…… o(n!)# 每一步后 原问题的规模是减少了 ,但是数据的同质性却破坏了:# 因为原问题的数组是连续的,子问题的数组不是连续的 这破坏了数据同质性的原则. ## 所以后面的思路就是 将不连续的数组 转换为连续的数组,这样子问题和原问题# 数据结构同质,且数据规模-1,

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

A:m段最大字段和问题 https://www.cnblogs.com/yinbiao/p/9314528.html B:map的使用(根本就不是dp!!!) https://www.cnblogs.com/yinbiao/p/9314605.html C:裸LIS问题 https://www.cnblogs.com/yinbiao/p/9150889.html D:状态压缩dp(还没有弄清楚) ..... E:裸LIS问题 https://www.cnblogs.com/yinbiao/p/9

【解题报告】[动态规划] - PID90 / 未出现的子串

原题地址:http://www.rqnoj.cn/problem/90 解题思路:题目看起来不太像动态规划... 我用一个数组f[i][j]来表示在数组第i个元素的后面第一次出现j的位置,为-1则是没出现过. 然后每次查找最大的位置即可.如题目例子中: f   1  3  5  2  4  1  3  5  2  2  2  2  3  4  1  5  3  2----------------------------------------------------------- 1  1  6

【解题报告】[动态规划]RQNOJ PID2 / 开心的金明

原题地址:http://www.rqnoj.cn/problem/2 解题思路:背包问题. 状态转移方程:DP[i][j]=max(DP[i-v[j]][j-1]+p[j]*v[j],DP[i][j-1]) DP[i][j]表示最多话费i的钱,购买前j+1个物品所能达到的最大价值. 解题代码: 1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 i

leetCode解题报告5道题(九)

题目一:Combinations Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example,If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 分析: 题意给我们一个数字n, 和一个数字k,让我们求出从 1~~n中取出k个数所能得到的组合数 所

leetCode解题报告5道题(八)

题目一: Populating Next Right Pointers in Each Node Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the

poj分类解题报告索引

图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Journey poj1724 - ROADS(邻接表+DFS) BFS poj3278 - Catch That Cow(空间BFS) poj2251 - Dungeon Master(空间BFS) poj3414 - Pots poj1915 - Knight Moves poj3126 - Prim

NOIP 2006 解题报告

第一题: 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为(Mars单位),新产生的珠子的头标记为m,尾