1、前言

大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤。虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下。

2、lis 最长上升子序列

唯一一道裸题,但是O(n^2)过不了,临时看了看O(n log n)的二分做法和线段树做法。先来讲讲简单的二分做法,其本质就是在O(n^2)上进行优化,需要证明一个结论。设当前处理数列第k位,存在:

  (1)a[i]<a[j]<a[k];

  (2)i<j<k;

  (3)f[i]=f[j]。

  此时我们选择a[i]好还是a[j]好?显然是a[i]好。为什么?倘若存在a[i]<a[x]<a[j],i<x<j,则选择a[i]可以得到更长的子序列——a[i],a[x],a[k]……这样,对于f[t]=k,我们只需要保存a[t]值最小的那个t了,可以证明得f数组将会单调递增,故我们每次不需要向前每一位都进行查找,而可以进行二分查找,故时间复杂度为O(n log n)。

------------------------------------------------------------------------------------------------------

#include<cstdio>

int min(int a,int b) { return (a<b)?a:b; }

int v[200010],n,x,ans;

int main()
{
  freopen("lis.in","r",stdin);
  freopen("lis.out","w",stdout);
  scanf("%d", &n);
  for (int i=1;i<=n;i++)
  {
    scanf("%d",&x);
    int l=1,r=ans,mid=(l+r)>>1,loc=0;
    while (l<=r)
    {
      if (v[mid]<=x) loc=mid,l=mid+1;
      else r=mid-1;
      mid=(l+r)>>1;
    }
    if (loc==ans) v[++ans]=x;
    else v[loc+1]=min(v[loc+1],x);
  }
  printf("%d\n",ans);

}

------------------------------------------------------------------------------------------------------

3、chess 黑白棋盘

根据题目分析,我们需要维护该列是否存在棋子;该行是否存在棋子;由于n<=15,我们可以考虑二进制状态压缩进行转移,最多有2^(n+1)种状态。设f[i][j]为当前第i行,状态为j(压缩的二进制状态 )时的方案数。今天才刚刚学会用&、^、|等位运算符,上次写状压的时候还是手写的。。。方程:f[i][j]=sum{f[i-1][j^(1<<(k-1))]} (k∈[1,n],j&(1<<(k-1)),!a[i][k])

代码:

------------------------------------------------------------------------------------------------------

#include <cstdio>
#define MOD 1e9+7

int n,a[20][20],f[20][100000],ans;
char ch;

int main()
{
  freopen("chess.in","r",stdin);
  freopen("chess.out","w",stdout);
  scanf("%d",&n);
  for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    {
      do ch=getchar(); while ((ch!='0')&&(ch!='1'));
      a[i][j]=ch-'0';
    }
  f[0][0]=1;
  for (int i=1;i<=n;i++)
    for (int j=0;j<1<<n;j++)
    {
      f[i][j]=f[i-1][j];
      for (int k=1;k<=n;k++)
        if ((j&(1<<(k-1))) && (!a[i][k])) 
        {
          f[i][j]+=f[i-1][j^(1<<(k-1))];
          if (f[i][j]>=MOD) f[i][j]-=MOD;
        }
    }
  for (int i=0;i<1<<n;i++) { ans+=f[n][i]; if (ans>=MOD) ans-=MOD; }
  printf("%d",ans);
  return 0;
}

------------------------------------------------------------------------------------------------------

4、bound 多背包问题

背包问题,但是需要用到单调队列优化。题解有点没懂?但是看代码大概清楚了。

------------------------------------------------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#define MAXN 10005
using namespace std;

int q[MAXN],f[MAXN],g[MAXN];
int n,m,s,w,v;

int dp(int x,int y) { return g[x]+(y-x)/w*v; }

int main()
{
  freopen("bound.in","r",stdin);
  freopen("bound.out","w",stdout);
  scanf("%d %d",&n,&m);
  for (int i=1;i<=n;i++)
  {
    scanf("%d %d %d",&s,&w,&v);
    for (int start=0;start<w;start++)
    {
      int tail=0,head=1;
      for (int j=start;j<=m;j+=w)
      {
        while (head<=tail && (j-q[head])/w>s) ++head;
        while (head<=tail && dp(q[tail],j)<=dp(j,j)) --tail;
        q[++tail]=j;
        f[j]=dp(q[head],j);
      }
    }
    swap(f,g);
  }
  int ans=0;
  for (int i=0;i<=m;i++) ans=max(ans,g[i]);
  printf("%d",ans);
  return 0;
}

------------------------------------------------------------------------------------------------------

5、matrix 子矩阵

也是所有题目中最需要码力的了吧,首先步骤比较复杂,情况比较繁琐,但是没有什么需要优化的地方。由于必定存在某条直线将三个矩阵割开,主要思路为枚举切割线,然后就只需要考虑两个矩阵的情况了。

6、windy windy数

数位动态规划,考试时想出来了但是没写下去。由于我们所需的信息明显:当前确定的数是否小于原数的这些位所对应的数;最后一位数;是否存在前导0,所以用记忆化搜索可能更易理解。下面代码来自yxj。

------------------------------------------------------------------------------------------------------

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

int p[20], r[20];
int f[20][20][2][2];
int a, b;

int dfs(int pos, int last, int s, int zero) {
  if (pos > 10) return s == 0 && zero == 0;
  int &u = f[pos][last][s][zero];
  if (u != -1) return u;
  u = zero == 0 && (r[pos] || s == 0);
  for (int i = 0; i <= 9; ++i) {
    if (abs(last - i) < 2) continue;
    int ns = i > p[pos] ? 1 : (i == p[pos] ? s : 0);
    u += dfs(pos + 1, i, ns, i == 0);
  }
  return u;
}

int tot(int x) {
  for (int i = 0; i <= 10; ++i) {
    p[i] = x % 10;
    r[i] = x;
    x /= 10;
  }
  memset(f, -1, sizeof(f));
  return dfs(0, 11, 0, 0);
}

int main() {
  freopen("windy.in", "r", stdin);
  freopen("windy.out", "w", stdout);

  cin >> a >> b;
  cout << tot(b) - tot(a - 1) << endl;
}

------------------------------------------------------------------------------------------------------

动态规划大合集II的更多相关文章

  1. [题解+总结]动态规划大合集II

    1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...

  2. [题解+总结]NOIP动态规划大合集

    1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...

  3. NOIP动态规划大合集

    1.前言 NOIP2003-2014动态规划题目大合集,有简单的也有难的(对于我这种动态规划盲当然存在难的),今天就把这些东西归纳一下,做一个比较全面的总结,方便对动态规划有一个更深的理解. 2.NO ...

  4. Lucene搜索方式大合集

    package junit; import java.io.File; import java.io.IOException; import java.text.ParseException; imp ...

  5. 【收藏】Java多线程/并发编程大合集

    (一).[Java并发编程]并发编程大合集-兰亭风雨    [Java并发编程]实现多线程的两种方法    [Java并发编程]线程的中断    [Java并发编程]正确挂起.恢复.终止线程    [ ...

  6. 从零开始学数据分析,什么程度可以找到工作?( 内附20G、5000分钟数据分析工具教程大合集 )

    从零开始学数据分析,什么程度可以找到工作?( 内附20G.5000分钟数据分析工具教程大合集 )   我现在在Coursera上面学data science 中的R programming,过去很少接 ...

  7. 直接拿来用!Facebook移动开源项目大合集

    直接拿来用!Facebook移动开源项目大合集 时间:2014-04-22 15:37 作者:唐小引 随着iOS依赖管理工具CocoaPods和大量第三方开源库成熟起来,业界积累了大量的优秀开源项目. ...

  8. python字符串操作实方法大合集

    python字符串操作实方法大合集,包括了几乎所有常用的python字符串操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下:   #1.去空格及特殊符号 s.st ...

  9. 【Oracle教程资源大合集】Oracle数据库免费学习资源汇总

    Oracle的产品非常丰富,各类学习资源也五花八门,本文将介绍Oracle官方的免费教程与风哥整理的Oracle视频教程: 1.Oracle帮助中心 Oracle帮助中心也称为Oracle文档中心,这 ...

随机推荐

  1. Java学习清单

    转自: csdn/zuochao_2013/article/details/76795164   ·   Java基础部分 *Java基础才是重中之重,只有基础打牢了,学习各种框架才能游刃有余. 1, ...

  2. CyclicBarrier一组线程相互等待

    /** * CyclicBarrier 一组线程相互等待 */ public class Beer { public static void main(String[] args) { final ; ...

  3. golang --学习笔记 运行时间计算

    package main import ( "fmt" "time" ) func main() { start := time.Now() //do some ...

  4. MySQL如何定位并优化慢查询sql

    1.如何定位并优化慢查询sql a.根据慢日志定位慢查询sql SHOW VARIABLES LIKE '%query%'      查询慢日志相关信息 slow_query_log 默认是off关闭 ...

  5. 前端通过js获取微信公众号用户的唯一标识符openId

    微信公众号程序开发的时候,获取用户信息的时候,需要用到用户的openId,openId是微信用户的唯一标识符,这个操作可以后台实现也可以前端实现,之前项目里是通过后台来获取的,好像用到了一些三方的包, ...

  6. 前端小插件之手写js循环滚动特效

    很多前端都离不开滚动的特效,调用插件繁琐,后期更改麻烦,考虑到这些因素,自己写了一套无限循环滚动的小特效. 首先滚动特效很好写,用css就可以完成,下面写一个基础css向上循环滚动特效 html &l ...

  7. 实验吧——你真的会PHP吗?(intval范围 php中\00的利用)

    题目地址:http://ctf5.shiyanbar.com/web/PHP/index.php 抓包在header中发现提示 访问得到源码 <?php $info = "" ...

  8. 英语cabardine麝香cabardine单词

    麝香(cabardine)是麝科动物林麝Moschus berezovskii Flerov. 马麝M. sifanicusPrzewalski或原麝M.moschiferus L.雄体香囊中的干燥分 ...

  9. SAP里SE38设置模板

    经验丰富些的大佬们都会有一套自己的风格,比如report主程序里几个form,常见的fieldcat的宏定义,常见的一些数据定义等等. 1.使用事物代码SE38进入编辑器. 2.点击客户端最右下角的文 ...

  10. 【团队项目1】 团队展示&选题

    一.团队展示 1. 队名:这次稳了 2. 队员: 莫少政 3117004667 (队长) 黄思扬 3117004657 余泽端 3117004679 江海灵 3117004658 温治乾 311700 ...