二维

P1006 传纸条(二维、三维dp)

做~自己de王妃 提交于 2020-02-08 10:15:14
P1006 传纸条 输入输出样例 输入 #1 复制 3 3 0 3 9 2 8 5 5 7 0 输出 #1 复制 34 说明/提示 【限制】 对于 30% 的数据,1≤m,n≤10; 对于 100% 的数据满1≤m,n≤50 NOIP 2008提高组第三题 思路如下 这一题应该是可以看成由两种解法,但是也可以看成一种解法,题解三四可以看成是题解一 ,优化掉一维的结果。 题解传送门 题解一(四维dp) # include <iostream> # define maxn 55 using namespace std ; int f [ maxn ] [ maxn ] [ maxn ] [ maxn ] , a [ maxn ] [ maxn ] ; int n , m ; int max_ele ( int a , int b , int c , int d ) { if ( b > a ) a = b ; if ( c > a ) a = c ; if ( d > a ) a = d ; return a ; } int main ( ) { cin >> n >> m ; for ( int i = 1 ; i <= n ; i ++ ) for ( int j = 1 ; j <= m ; j ++ ) cin >> a [ i ] [ j ] ; for ( int i =

子矩阵的和---二维前缀和模板题

↘锁芯ラ 提交于 2020-02-07 15:12:49
题目链接: https://www.acwing.com/problem/content/798/ 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1000+10; int nums[N][N],s[N][N]; int n,m,q; int main(void){ scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++){ for(int j = 1;j<=m;j++){ scanf("%d",&nums[i][j]); s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + nums[i][j]; } } int x1,y1; int x2,y2; while(q--){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%d\n",s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]); } return 0; } 来源: https://www.cnblogs.com/doubest/p/12272932.html

背包问题:二维费用背包问题

ぐ巨炮叔叔 提交于 2020-02-06 12:35:46
问题描述 有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。 每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。 求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。 输出最大价值。 输入格式 第一行两个整数,N,V,M,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。 接下来有 N 行,每行三个整数 vi,mi,wi,用空格隔开,分别表示第 i 件物品的体积、重量和价值。 输出格式 输出一个整数,表示最大价值。 输入样例 4 5 6 1 2 3 2 4 4 3 4 5 4 5 6 输出样例: 8 思路 和01背包问题一样, 这里将01背包问题改成2维 代码 # include <iostream> # include <algorithm> using namespace std ; const int N = 1010 ; int f [ N ] [ N ] ; int n , V , M ; int v , m , w ; int main ( ) { cin >> n >> V >> M ; for ( int i = 1 ; i <= n ; i ++ ) { cin >> v >> m >> w ; for ( int j = V ; j >= v ; j -- ) {

搜索二维矩阵II

三世轮回 提交于 2020-02-05 05:19:50
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性: 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例: 现有矩阵 matrix 如下: [ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ] 给定 target = 5,返回 true。 给定 target = 20,返回 false。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 从矩阵左下开始比较,容易一些; class Solution { public : bool searchMatrix ( vector < vector < int >> & matrix , int target ) { int row = matrix . size ( ) ; if ( row == 0 ) { return false ; } int col = matrix [ 0 ] . size ( ) ; if ( col == 0 ) {

二维线段树(树套树)

混江龙づ霸主 提交于 2020-02-03 03:01:11
解析待写 例题: 2020 CCPC Wannafly Winter Camp Day5 I 题 代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e3+10; int n, m1, m2; int x, y, xl, xr, yl, yr; ll w; ll a[N][N]; void add(){ a[xl][yl] += w; a[xl][yr+1] -= w; a[xr+1][yl] -= w; a[xr+1][yr+1] += w; } ll tree[4*N][4*N]; void up_y(int ox, int oy, int l, int r, int f){ if(l == r){ if(f) tree[ox][oy] = w; else tree[ox][oy] = max(tree[ox<<1][oy], tree[ox<<1|1][oy]); return ; } int mid = l+r >> 1; if(y <= mid) up_y(ox, oy<<1, l, mid, f); else up_y(ox, oy<<1|1, mid+1, r, f); tree[ox][oy] = max(tree[ox][oy<<1], tree

vj第一场

霸气de小男生 提交于 2020-02-02 00:47:11
未完待续 第一场: 主要有三道 思维题 得到经验 对于看上去很复杂的题目 其实 在某种 程度上很可能就是 关于思维或者是数学方面的找规律题目 应该耐下心来 慢慢找 再就是 一到对于超时问题的优化 可以用set代替 数组的遍历 从而节省 时间 以及lower_bound 和 upper_bound 两种函数 在set中寻找目标的值写法 不只可以单单应用在数组中 还有就是 通过这道题目 也可以用 优先队列的方法进行解答 应该给予相应的重视与学习 下面要学习的相关算法: 1.数据的离散化 这个已经用到很多了 学习一下 2.最短路和最小生成树算法的学习 主要最短路再学习flyod算法和最小生成树再了解 迪杰斯特拉算法 加上 优先队列的 的优化算法 3.线段树对于最小子区间和的维护 以及要复习 线段树其他的相关操作 补题任务 F J L先完成这三道 F: cnt大小的不断变化 代表着不同类型的消息 他们数的大小也就是他们产生的先后顺序 每一个数就代表着是一个消息 对应着三种操作 1:编号为x的应用生成一条未读消息 2:吧编号为x的应用所有的消息标记为已读 不管是否已经有读过的消息 3:把前t条消息标记为已读 进行完每一次操作后 输出当前手机上所有应用 未读的消息总数是多少 用 vector 和 set 这两个stl函数 来完成 #include <cstdio> #include

二维费用的背包问题

被刻印的时光 ゝ 提交于 2020-02-01 20:02:53
有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。 每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。 求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。 输出最大价值。 输入格式 第一行两个整数,N,V,M,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。 接下来有 N 行,每行三个整数 vi,mi,wi,用空格隔开,分别表示第 i 件物品的体积、重量和价值。 输出格式 输出一个整数,表示最大价值。 数据范围 0<N≤1000 0<V,M≤100 0<vi,mi≤100 0<wi≤1000 输入样例 4 5 6 1 2 3 2 4 4 3 4 5 4 5 6 输出样例: 8 完整代码: #include <bits/stdc++.h> #define int long long using namespace std; int n,v,m; int f[110][110];//f[i][j]表示体积为i,重量为j时的最大价值 signed main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>v>>m; for(int i=0;i<n;i++){ int vi,wi,val; cin>>vi>>wi>>val; for

【LeetCode】74. 搜索二维矩阵(JAVA)

时光总嘲笑我的痴心妄想 提交于 2020-01-31 05:23:45
原题地址: https://leetcode-cn.com/problems/search-a-2d-matrix/submissions/ 题目描述: 编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: 每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。 示例 1: 输入: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 输出: true 示例 2: 输入: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 13 输出: false 解题方案: 看到题目第一反应是把二维矩阵存到一维矩阵里,但是想了一下这不是遍历嘛时间复杂度太高了,所以就想先二分查第一列里小于target的最大值,然后再在这一行二分,由于当数组中值小于target时可能是想找的值,所以此时low=mid,结果为了处理特殊情况还加了不少判断,结果在看题解的时候发现可以直接用处理下标的方式把二维数组看作一维,完全忘了这个方法。。。 代码: class Solution { public boolean searchMatrix(int[][] matrix, int

算法 中等 | 38. 搜索二维矩阵 II

[亡魂溺海] 提交于 2020-01-31 04:44:46
算法 中等 | 38. 搜索二维矩阵 II 题目描述 样例1 样例2 java题解 C++题解 python题解 题目描述 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数。 这个矩阵具有以下特性: 每行中的整数从左到右是排序的。 每一列的整数从上到下是排序的。 在每一行或每一列中没有重复的整数。 样例1 输入: [ [ 3,4 ] ] target = 3 输出:1 样例2 输入: [ [ 1, 3, 5, 7 ] , [ 2, 4, 7, 8 ] , [ 3, 5, 9, 10 ] ] target = 3 输出:2 java题解 从左下角开始,往右上角逼近 public class Solution { public int searchMatrix ( int [ ] [ ] matrix , int target ) { // check corner case if ( matrix == null || matrix . length == 0 ) { return 0 ; } if ( matrix [ 0 ] == null || matrix [ 0 ] . length == 0 ) { return 0 ; } // from bottom left to top right int n = matrix . length ; int m =

二维数组数组详解

ぐ巨炮叔叔 提交于 2020-01-30 12:49:31
转载自: 胡小兔博客,https://www.cnblogs.com/RabbitHu/p/BIT.html %%大连市理科状元。 “高级”数据结构——树状数组! ※本文一切代码未经编译,不保证正确性,如发现问题,欢迎指正! 1. 单点修改 + 区间查询 最简单的树状数组就是这样的: void add(int p, int x){ //给位置p增加x while(p <= n) sum[p] += x, p += p & -p; } int ask(int p){ //求位置p的前缀和 int res = 0; while(p) res += sum[p], p -= p & -p; return res; } int range_ask(int l, int r){ //区间求和 return ask(r) - ask(l - 1); } 2. 区间修改 + 单点查询 通过“差分”(就是记录数组中每个元素与前一个元素的差),可以把这个问题转化为问题1。 查询 设原数组为 a [ i ] a[i], 设数组 d [ i ] = a [ i ] − a [ i − 1 ] ( a [ 0 ] = 0 ) d[i]=a[i]−a[i−1](a[0]=0),则 a [ i ] = ∑ i j = 1 d [ j ] a[i]=∑j=1id[j],可以通过求 d [ i ] d[i