dp题单vjudge 8.17
HDU-1024 Max Sum Plus Plus
https://acm.hdu.edu.cn/showproblem.php?pid=1024
可以想到用dp过,但是无论时间和空间都不够,然后就不会了
https://www.cnblogs.com/wuwangchuxin0924/p/6546901.html
先写出转移方程,然后发现如果把其中一部分用其他的东西储存起来,就不需要重复寻找,直接使用就行了
3天的沉淀o( ̄┰ ̄*)ゞ
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[1000006]={0};
int b[1000006]={0};
int dp[1000006]={0};
const int inf=0x7ffffffff;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,k;
while(cin>>k>>n){
for(int i=1;i<=n;++i){
cin>>a[i];
}
for(int i=1;i<=n;++i){
b[i]=dp[i]=0;
}
for(int i=1;i<=k;++i){
b[i-1]=dp[i-1];
for(int j=i;j<=n;++j){
b[j]=max(b[j-1],dp[j]);
dp[j]=dp[j-1]+a[j];
dp[j]=max(dp[j],b[j-1]+a[j]);
}
}
int ans=-inf;
for(int i=k;i<=n;++i){
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
}
return 0;
}
HDU-1047 Doing Homework
难死我了!查阅博客
https://www.cnblogs.com/dilthey/p/7594497.html
开幕雷击,谢谢。
使用二进制,说实话在写这个题目的时候有乱想到,但是感觉更像是搜索因为时间复杂度就放弃,遂仔细梳理一下
一门课程完成的状态可以从未完成的状态转移过来,前一个未完成的状态是在之前得到过的最优解
和搜索有什么区别呢?当完成n门课的时候,实际上我已经把每一种顺序都跑了一次
好像回归到了dp最初的定义:把要重复使用的数据记录下来,下一次就不需要再算了
这道题的状态转移方程是好想的。
如果是直接搜索:对于一个规划好的顺序来看,假使我用solve函数去写,一定是一步步走下去的,这样就不好,但是dfs感觉应该是可以完成的,因为思维太朴素了,实际上搜索也一定不是把每一种顺序重新跑一遍,而是在当前的顺序下继续走下去而已。
算下时间复杂度,如果采取的措施是把选过的东西打上标记,不会重复搜索,那么相当于是 \(O(N^N)\) 然后 \(N<15\)。其实是可以的吧
很不喜欢老题,因为很多数据的范围都没有给好,但是不做心里又难受,要消耗好多时间,尝试写一下dfs
因为题型知道了,接下来去找几道专门的状压dp做做就好,说实话要怎么保证字典序最小是一点想法都没有,还是太弱。但是评论区说数据给的很糟,不用考虑这一点,开心!ヾ(≧▽≦*)o
尝试写下,当做是锻炼代码能力了
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int n;
map<int,string> p;
int a[20];//jie zhi
int b[20];//hao shi
int vis[20]={0};
int ans=0x7ffffffff;
vector<int> ansv;
vector<int> v;
void init(){
ans=0x7ffffffff;
p.clear();
for(int i=1;i<=n;++i){
vis[i]=0;
}
v.clear();
ansv.clear();
}
void change(){
ansv.clear();
for(auto i:v){
ansv.push_back(i);
}
}
void dfs(int step,int now,int score){
if(step==n) {
if(score<ans){ change();ans=score; }
return;
}
for(int i=1;i<=n;++i){
if(vis[i]==1) continue;
vis[i]=1;
int t=now+b[i];
int delt=t-a[i];
if(delt<=0) delt=0;
int ss=score+delt;
v.push_back(i);
dfs(step+1,t,ss);
v.pop_back();
vis[i]=0;
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int time;
cin>>time;
while(time--){
cin>>n;
init();
for(int i=1;i<=n;++i){
string s;
cin>>s;
p[i]=s;
cin>>a[i]>>b[i];
}
dfs(0,0,0);
cout<<ans<<endl;
for(auto i:ansv){
cout<<p[i]<<endl;
}
}
return 0;
}
出乎意料的快速的写完了。发现时间复杂度算错数字了,时间复杂度早就超了。看来是没有理解透彻状压dp
找些简单的状压做做
突然开窍,搜索和dp的区别就是
假如我要找从 n个科目-------转移到-------k个科目
如果是搜索,则是把每一种从 0-n的情况全都延续下去,一直到k个课程
相当于如果是从 n-k有m步,从0-n 有M 步,那样搜索总共走过的步数是 m*M
而dp来说我是在跑完 M的情况下,找出最优秀的情况然后转移到 k ,总的步数是 M+m
差不多就是这样的意思吧
非常聪明!o( ^ ▽ ^ )o
确实如同一篇博客所说 : 状压dp的特征就是 : 和搜索差不多 也是一种暴力
这一篇博客我印象非常深刻,以前曾分工动态规划,但是没有看懂
然后考虑如何保证字典序
假如我是从字典序小的一方开始遍历,那样我得到的第一个合适的最小值对应的方案就是字典序最小的方案
dp实现思路:
对于k节课程的状态,是由 这k个课程分别让每一个没有完成的状态转移过来,小的遍历然后取min值,大遍历的i节课程
关于转移到 选了k的状态,用一个tem=(1<<i)
然后用k&tem即可,如果不为0则是这个书对于k来说是我想选的,然后把这一位给变为0,用异或即可,得到之前的状态
过程中我需要找到每一种状态的最优解,所以就是每一种状态都需要去跑一遍,为了能充分的传递,要从1的数目最少的开始。要怎么样才能把这些数字挑出来呢?
发现其实根本就不需要把这些数字给跳出来,如果是从1开始然后一直到(1<<n)就是朴素的遍历也就能保证需要的状态在之前就已经求得过了。
从二进制位上开始考虑 需要的位数上全是1的情况的数的大小其实就已经比所有能传递到这样的状态的数字更大了,所以只要从小往大遍历就完全足够!
很多代码实现的思路上的东西就是不太好讲,曾经也抱怨为什么很多博客的作者根本就不讲思路
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int cnt=0;
int n;
map<int,string> p;
int a[100]={0};//jiezhi
int b[100]={0};//haoshi
int dp[40000]={0};
int tt[40000]={0};
vector<int> v[40000];//记录 字符串(顺序)
void change(int pre,int now,int add){
v[now].clear();
for(auto i:v[pre]){
v[now].push_back(i);
}
v[now].push_back(add);
}
void init(){
p.clear();
for(int i=1;i<=(1ll<<n);++i){
v[i].clear();
dp[i]=0x7fffffff;
tt[i]=0;
}
}
signed main(){
int timee;
cin>>timee;
while(timee--){
cin>>n;
init();
int ans=0x7fffffff;
for(int i=1;i<=n;++i){
string s;
cin>>s;
p[i]=s;
cin>>a[i]>>b[i];
}
int bb=(1ll<<n)-1;
for(int i=1;i<=bb;i++){
int tem=1;
int cnt=0;
while(tem<=i){
cnt++;
if((tem&i)!=0){
int x=i^tem;
tt[i]=tt[x]+b[cnt];
int y=tt[i]-a[cnt];
if(y<0) y=0;
int temm=y+dp[x];
if(dp[i]<temm) {tem<<=1;continue;}
else{
dp[i]=temm;
change(x,i,cnt);
}
}
tem<<=1;
}
}
cout<<dp[(1<<n)-1]<<endl;
for(auto i:v[(1<<n)-1]){
cout<<p[i]<<endl;
}
}
return 0;
}
一遍过!舒服了
写完了确实觉得比较简单
dp题单vjudge 8.17的更多相关文章
- 【DP_树形DP专题】题单总结
转载自 http://blog.csdn.net/woshi250hua/article/details/7644959#t2 题单:http://vjudge.net/contest/123963# ...
- 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)
模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...
- (计数器)NOIP模拟赛(神奇的数位DP题。。)
没有原题传送门.. 手打原题QAQ [问题描述] 一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,…,9.其中—个页码不含多余的0,如N=1234时第5页不是00 ...
- 几个相似的DP题
HDU1398 题意:把一个整数分拆成1.4.9.16.…….256.289(注意:只到289)这17个完全平方数的和,有几种方法. 解法不用说自然是DP,因为搜索显然超时. (这样的题我一般不敢开i ...
- CF dp 题(1500-2000难度)
前言 从后往前刷 update 新增 \(\text{\color{red}{Mark}}\) 标记功能,有一定难度的题标记为 \(\text{\color{red}{红}}\) 色. 题单 (刷过的 ...
- AC自动机题单
AC自动机题目 真的超级感谢xzy 真的帮到我很多 题单 [X] [luogu3808][模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P38 ...
- Codeforces Round #369 (Div. 2)---C - Coloring Trees (很妙的DP题)
题目链接 http://codeforces.com/contest/711/problem/C Description ZS the Coder and Chris the Baboon has a ...
- 4817 江哥的dp题d
4817 江哥的dp题d 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 已知1-N的排列P的LIS(最长上 ...
- 4809 江哥的dp题c
4809 江哥的dp题c 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有两个数x,y,一开始x=1,y= ...
- 4816 江哥的dp题b
4816 江哥的dp题b 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 给出两个1-N的随机排列A,B.若 ...
随机推荐
- Devexpress GridView 单元格输入检验
实现效果 打开设计器 找到CellValueChanged事件 编写代码 private void gvmain_CellValueChanged(object sender, DevExpress. ...
- wget 提示 "无法验证 xxxx.xxx 的由 “xxx” 颁发的证书: 无法本地校验颁发者的权限。"
有一天在使用 wget 下载文件时,出现了无法验证证书的提示: $ wget https://github.com/zayronxio/Mkos-Big-Sur/releases/download/0 ...
- WKCTF RE
WKCTF so_easy 安卓逆向,关键的check逻辑都在native层里面 主要是很多层的异或操作 除了Z3和爆破想不到其他方法了 from z3 import * src = [ 0xAE, ...
- 在虚拟机CentOS中安装docker
公众号本文地址:在虚拟机CentOS中安装Docker 1.关闭防火墙 docker需要用到网络,所以需要关闭防火墙.进入管理员模式获得权限后进行关闭. su 关闭防火墙: systemctl dis ...
- 基于GitLab+Jenkin-CICD方案实践
前言 笔录于2022- 官网:https://about.gitlab.com/ 参考文档:https://docs.gitlab.com/ee/ci/ 清华源:清华大学开源软件镜像站 | Tsing ...
- 2024.7.5-2024.7.20 HA省学会集训游记(焦作一中)
这是一篇长篇小说 DAY1 除了DAY4-DAY5个别内容以外,这些都是补的,但是全写完有太多了qwq,挑题写了 树状数组和线段树基础 很多都是一些模板题,太模板的题不再做太多解释 题目: P4062 ...
- MyBatisPlus——简介
概述 MyBatisPlus(简称MP)是基于MyBatisPlus框架基础上开发的增强型工具,旨在简化开发.提高效率 国内开发的技术 特性 无侵入:只做增强不做改变,不会对现有工程产生影响 强大的C ...
- 大一下的acm生活
在一个名气不大的211学校刷题的日常. 感觉这些算法题好难啊! 最近有好多实验室要招新,不知道该怎么办,自己只想就业,并不想升学,好烦! 真枯燥,好无聊. 现在要学习相关的网页设计和网站建设,例如配色 ...
- LeetCode 1819. 序列中不同最大公约数的数目(数论)
题目描述 给你一个由正整数组成的数组 nums . 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数. 例如,序列 [4,6,16] 的最大公约数是 2 . 数组的一个 子序列 本质 ...
- Xcode 12 引用缺失包:libstdc++.tbd libstdc++.6.tbd libstdc++.6.0.9.tbd引发的一系列问题解析
升级到xcode12后会有libstdc++.tbd libstdc++.6.tbd libstdc++.6.0.9.tbd 等库缺失的情况,并引发一些列的 Undefined symbols for ...