2月三号 集训第三天
来源:互联网 发布:域名城,潇湘华 编辑:程序博客网 时间:2024/04/30 14:36
主题:背包
背包是利用动态规划
主要形式:
1.一维形式
int v[100],n,w[100],dp[100];
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++){
for(int j = m; j >= w[i]; j--){
dp[j] = max(dp[j],dp[j - w[i]]+v[i]);
}
}
printf("%d", dp[m]);//从大到小保持不会爆
2.二维形式
函数实现 0-1 背包
#include<cstdlib>
#include<cstdio>
using namespace std;
int V[3500][15000];//在main函数外面能把一/二维数组开的更大一些
int knapSack(int n, int m, int *w, int *v){
for(int i = 0'; i < n; i++){
V[0][i] = 0;
}
for(int i = 0; i < m; ++){
v[i][0] = 0;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m]; j--){
if(j < w[i]){
V[i][j] = V[i-1][j];
}
else {
V[i][ j] =max(V[i-1][j],V[i-1][j+w[i]]+v[i]);
}
}
}
int j = m;
for(int i =n ;i > 0; i--){
if(V[i][j] > V[i][j-1]){
j = j - w[i];
}
else ;
}
return V[n][m];
}
int main(){
itn n, m,w[500],v[500];
memset(V,0,sizeof(V));
while(~scanf("%d%d", &n,&m)){
for(int i = 1; i <= n; i++){
scanf("%d%d", &w[i], &v[i]);
printf("%d\n", KsnapSack(n,m,w,v));
}
return 0;
}
3.背包不一定为+,还可变形为×
for(int i = 1; i <= n ; i++)
for(int j = m; j >= w[i] ; j--)
.... = max( , )
只是为了得到最接近m的组合
4.二维数组可以用下标来表示一个平衡状态
如果i下标会小于零的话,重新定义一个零点.
例http://acm.hust.edu.cn/vjudge/contest/view.action?cid=69281#problem/Cbalance
定义7500为零点.
dp[0][7500] = 1;//m表示砝码的个数,n表示距离中心的距离的个数
for(int i = 1; i <=n; i++){
for(int j = 1; j <= m; j++){
for(int k = 0; k <= 15000; k++){
dp[i][k + w[i]*v[j]]+=dp[i-1][k];
}
}
}
printf("%d", dp[m][7500]);
5.最长不下降子序列
一.n*2复杂度的一般做法(大于10000个元素时不再适用)
#include<stdio.h>
int main(){
int num[100],a[100];
int n;
scanf("%d", &n)
for(int i = 0; i <= n; i++){
scanf("%d", &a[i]);
}
for(int i = 0; i <= n; i++){
num[i] = 1;
for(int j = 0; j < i; j++){
if(a[i] > a[j]&&num[j]+1>num[i]){
num[i] = num[j] +1;
}
}
int max = 0;
for(int i = 0; i < n; i++){
if(max < a[i])
max = a[i];
}
printf("%d\n", max);
}
return 0;
}
二.二分法 复杂度n*logn
int a[10000],num[10000];
int find(int len ,int n){
int left = 1, right = len;
int mid;
whie(left<=right){
if(a[mid] = n) return mid;
else if(a[mid] > n) right = mid - 1;
else if(a[mid] < n) left = mid + 1;
}
return left;
}
int main(){
int n;
while(~scanf("%d", &n)){
for(itn i = 1; i <= n; i++){
scanf("%d", a[i]);
}
num[1] = a[1];
int len = 1;
for(int i = 1; i <= n; i++){
int j = find(len ,a[i]);
num[j] = a[i];
if(j > len)
len = j;
}
printf("%d\n", len);
}
return 0;
}
- 2月三号 集训第三天
- 2017.8.2暑假集训第三天
- 集训第三天
- 集训第三天
- Android集训第三天
- 集训第三天,打卡
- 暑期集训第三天
- 2017暑假集训第三天
- 2月1号 集训第一天
- 第三天 11月2日
- XTU集训第三天16-7-19
- 1619-7 张良 十月三号总结 [连续第三天]
- 2017年2月16日 第三天
- 集训第三天(2017/8/2):继续刷搜索题
- 寒假集训第三天——栈和队列
- 2015郑州大学ACM暑期集训——第三天
- 2017.1.14——寒假集训第三天
- 暑假第三天 7月8日
- Mysql如何查询连续时间内的次数
- 《STL源码解析》读书笔记之allocator(1)
- 基础篇-5.26-回文素数,准确对齐(2/4更新)
- STL: sort
- 视听类--听闻
- 2月三号 集训第三天
- FreeRTOS学习笔记——互斥型信号量
- 利用StringEscapeUtils对字符串进行各种转义与反转义(Java)
- Yii 用户身份验证
- Linux下Perl的安装
- [IOS]手势识别(双击、捏、旋转、拖动、划动、长按)
- LoadRunner中参数化技术详解
- 嵌入式 fprintf和fscanf函数
- 第二章 表达式与运算符