背景

小杉的幻想来到了经典日剧《死亡拼图》的场景里……
被歹徒威胁,他正在寻找拼图(-.-干嘛幻想这么郁闷的场景……)。

突然广播又响了起来,歹徒竟然又有了新的指示。

小杉身为新一代的汤浅,有责任带领大家脱离危险!

(若对情节有任何疑问,请观看原剧)

描述

歹徒告诉小杉,他正在寻找的拼图块其实可以拼成N个 有顺序的 完整的拼图。

每个完整的拼图由若干个拼图块组成。

歹徒要求小杉把拼图按拼出的顺序划分成M个集合,一个拼图集合由若干个完整的拼图组成,并且总的拼图块的数目不超过T。并且,构成集合的拼图是不能交叉的,例如,当拼图1与拼图3被放在拼图集合1中之后,拼图2就只能放进拼图集合1或者不放进任何拼图集合。

小杉要找出划分成M个集合后,M个集合中最多能有多少个完整的拼图。

格式

输入格式

每组测试数据的
第一行有三个,为N,M,T(1<=N,M,T<=1000)
第二行有N个数,按照拼出拼图的顺序给出N个拼图分别含有多少个拼图块(拼图块的个数是不超过T的正整数,并且你不必考虑在现实中是否真正存在该个数的拼图)。

特别地,对于30%的数据,有1<=N,M<=100

输出格式

对每组数据输出一行一个数字,为M个拼图集合最多包含的拼图个数

样例1

样例输入1

  1. 6 2 4
  2. 1 1 3 1 2 2

样例输出1

  1. 5

限制

每个测试点1s

提示

对于样例数据,1个可行的方案如下
拼图集合1放拼图1和拼图2,
拼图集合2放拼图5和拼图6
于是最多可以放4个拼图

并且显然不存在能够放4个以上拼图的方案

来源

lolanv

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

题意:长度n的序列分成m段,每段选若干元素,使得总段数w不超过t,且选的最多

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

一开始想f[i][j][k]表示i个分j段,最后一段的w为k的最多拼图个数

然后像背包一样转移,不选i或者选i,选的话可能是从本段来的,也可能是刚好新开一段

把i滚动数组掉,维护一个mx[i][j]表示i个分j段段最大值,方便新开一段这个转移

注意f[i][j][0]=mx[i-1][j-1]

然后竟然做出来了,虽然很慢

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N=;
  7. int n,m,t,w[N];
  8. int f[N][N],mx[N][N];
  9. void dp(){
  10. for(int i=;i<=n;i++)
  11. for(int j=m;j>=;j--){f[j][]=mx[i-][j-];
  12. for(int k=t;k>;k--){
  13. int &now=f[j][k];
  14. if(k-w[i]>=) now=max(now,f[j][k-w[i]]+);
  15. mx[i][j]=max(mx[i][j],now);
  16. //printf("%d %d %d %d\n",i,j,k,now);
  17. }
  18. }
  19. }
  20. int main(int argc, const char * argv[]) {
  21. scanf("%d%d%d",&n,&m,&t);
  22. for(int i=;i<=n;i++) scanf("%d",&w[i]);
  23. dp();
  24. cout<<mx[n][m];
  25. return ;
  26. }

另一种很神的思路是,把后两个状态和状态值对换

f[i][j]=c(a,b)表示前i个选j个的段数为a且额外要b个段数

有点类似可行性,注意初始化

速度好快

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N=,INF=1e5;
  7. int n,m,t,w[N],ans=;
  8. struct data{
  9. int a,b;
  10. data(int x=INF,int y=INF):a(x),b(y){}
  11. };
  12. data min(data x,data y){
  13. if(x.a<y.a) return x;
  14. if(x.a>y.a) return y;
  15. if(x.a==y.a) return x.b<y.b?x:y;
  16. return x;
  17. }
  18. data f[N][N];
  19. void dp(){
  20. for(int i=;i<=n;i++) f[i][]=data(,);
  21. for(int i=;i<=n;i++)
  22. for(int j=;j<=i;j++){
  23. data tmp;
  24. if(w[i]+f[i-][j-].b<=t){tmp.a=f[i-][j-].a;tmp.b=f[i-][j-].b+w[i];}
  25. else{tmp.a=f[i-][j-].a+;tmp.b=w[i];}
  26. f[i][j]=min(f[i-][j],tmp);
  27. if(f[i][j].a<m) ans=max(ans,j);
  28. //printf("%d %d %d %d\n",i,j,f[i][j].a,f[i][j].b);
  29. }
  30. }
  31. int main(int argc, const char * argv[]) {
  32. scanf("%d%d%d",&n,&m,&t);
  33. for(int i=;i<=n;i++) scanf("%d",&w[i]);
  34. dp();
  35. cout<<ans;
  36. return ;
  37. }

Vijos1392拼拼图的小衫[背包DP|二维信息DP]的更多相关文章

  1. NOIP2009pj道路游戏[环形DP 转移优化 二维信息]

    题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编 ...

  2. 微信小程序条码、二维码生成模块

    代码地址如下:http://www.demodashi.com/demo/13994.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  3. 微信小程序生成带参二维码

    需求:生成小程序中的海报,需要小程序二维码可以使用户保存到本地在朋友圈分享 生成二维码工具类代码如下: package com.aone.foottalk.action.wx.util; import ...

  4. 关于.NET HttpClient方式获取微信小程序码(二维码)

    随着微信小程序的火热应用,市面上有关小程序开发的需求也多了起来.近来分析了一项生成有关生成微信小程序码的需求——要求扫码跳转到小程序指定页面(带参数):看了下小程序官方文档文档,结合网上的例子,未看到 ...

  5. dp --- 二维dp + 最大上升子序列

    <传送门> 滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 74477   Accepted: 27574 ...

  6. 微信小程序之生成二维码

    最近项目中涉及到小程序的生成二维码,很是头疼,经过多次摸索,整理出了自己的一些思想方法,如有不足,欢迎指正. 首先完全按照小程序的结构依次填坑. pages--index.wxml <view ...

  7. 微信小程序,获取二维码

    微信小程序,获取二维码 找到一篇很实用的博客,他已经写得很详细了,自己也懒得写,亲测有效 参考网址

  8. dp 二维乃至多维背包

    洛谷P1855 榨取kkksc03 分析:套路是很明显的01背包,但是这时受约束的变量有两个了,这种情况下就该用多维背包了 分析方法一样的,用dp[i][j][k]表示从前i个愿望中挑选总时间和总金钱 ...

  9. HDU 2159 FATE (DP 二维费用背包)

    题目链接 题意 : 中文题不详述. 思路 : 二维背包,dp[i][h]表示当前忍耐值为i的情况下,杀了h个怪得到的最大经验值,状态转移方程: dp[i][h] = max(dp[i][h],dp[i ...

随机推荐

  1. 最简单的轮播广告(原生JS)

    改变每个图片的opacity属性:来自学友刘斌 素材图片: <!DOCTYPE html> <html lang="en"> <head> &l ...

  2. .NET web开发之WebApi初试水

    前几天看了.NET的EF(Entity Framework),发现居然有这么先进的东西,只要操作几个类就可以完成数据库的增删查改,而且可以用数据库直接导出类(DB First).也可以用类来生成数据库 ...

  3. ALV中处理过滤掉的行

    有时候我们在ALV的时候,客户会对输出的数据进行二次筛选,这时候如果我们做全选(checkbox)系统会把我们过滤掉得数据也选择: 用下面的method就可避免此问题: DATA:it_rows TY ...

  4. 关于web软件信息安全问题资料的整理(四)

    整理出了几点解决方案 1.修护漏洞.对于防护的一方来看,如果先于攻击一方发现Web系统中存在的漏洞,尽早修复它们,就可以防患于未然,获得最低的防护成本.漏洞的修复方式并不是一定要依靠修改网页代码才可以 ...

  5. SharePoint如何关掉mysite. how to disable mysite creation

    一个很简单的问题 center admin --> application managment -->manage service application -->user profi ...

  6. .Net控件经验集合

    一.DropDownList默认选中 开始的笨方法: foreach (ListItem item in DropDownList1.Items)                       {    ...

  7. CLLocationManagerDelegate不调用didUpdateLocations (地图)

    这是因为xcode升级造成的定位权限设置问题.升级xcode6以后打开以前xcode5工程,程序不能定位.工程升级到xcode6编译时需要iOS8 要自己写授权,不然没权限定位.解决方法:首先在 in ...

  8. OC NSString(字符串)

    OC NSString(字符串) 多行文字字面量 NSString * string = @"abC" @"DEF" @"hjk" @&qu ...

  9. ASP.NET处理301重定向方法 带示例 (demo)

    System.Web.HttpContext.Current.Response.Status = "301 Moved Permanently"; System.Web.HttpC ...

  10. ORACLE手工删除数据库

    很多人习惯用ORACLE的DBCA工具创建.删除数据库,这里总结一下手工删除数据库实验的步骤,文中大量参考了乐沙弥的手动删除ORACLE数据库这篇博客的内容,当然还有Oracle官方相关文档.此处实验 ...