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.若 ...
随机推荐
- MRI roi图像合并
笔记来源:MRI roi的图像合并 dpabi小工具_哔哩哔哩_bilibili 1. 如果几个图像的维度不一致,需要先进行reslice 1)如何看图像的维度 以软件MRIcron为例, windo ...
- Coursera self-driving2, State Estimation and Localization Week4, LIDAR
operating principles 工作原理 Velodyne 加州,Hokuyo 日本,SICK 德国 TOF 就是用发出去收到的时间差和光速算距离 basic LIDAR models (2 ...
- babel-preset-env与stage-x的使用指南
babel介绍 babel总共分为3个阶段: 解析.转换和生成 babel本身不具有任何转换功能, 如果没有plugin,那么经过babel的代码和输入的是相同的. babel插件分为两种 语法插件: ...
- 扫描全能王启动鸿蒙原生应用开发,系HarmonyOS NEXT智能扫描领域首批
近期,"鸿蒙合作签约暨扫描全能王鸿蒙原生应用开发启动仪式"(简称"签约仪式")正式举行.合合信息与华为达成鸿蒙合作,旗下扫描全能王将基于HarmonyOS NE ...
- WaterCloud:一套基于.NET 8.0 + LayUI的快速开发框架,完全开源免费!
前言 今天大姚给大家分享一套基于.NET 8.0 + LayUI的快速开发框架,项目完全开源.免费(MIT License)且开箱即用:WaterCloud. 可完全实现二次开发让开发更多关注业务逻辑 ...
- SpringBoot 实现文件上传
参考:Java springboot进阶教程 文件上传功能实现 后端代码编写 常见错误分析与解决 在 Service 业务层接口中增加一个上传文件的方法 因为文件并不是上传至数据库中,所以不需要编写 ...
- 七,MyBatis-Plus 扩展功能:乐观锁,代码生成器,执行SQL分析打印(实操详细使用)
七,MyBatis-Plus 扩展功能:乐观锁,代码生成器,执行SQL分析打印(实操详细使用) @ 目录 七,MyBatis-Plus 扩展功能:乐观锁,代码生成器,执行SQL分析打印(实操详细使用) ...
- go 使用websocket
package chat import ( "encoding/json" "github.com/gorilla/websocket" "githu ...
- select框多选(利用Bootstrap-select)
前端HTML: <select id="usertype" multiple class="selectpicker" style="width ...
- 冒泡排序和一点优化(php)
function maopao($arr){ $len = count($arr);//获取数组的长度 //有多少个数组元素就最多就要排n-1次 for ($j=0;$j<$len-1;$j++ ...