首页 > 其他分享 >NFLS DP题单笔记(做不动了未完结)

NFLS DP题单笔记(做不动了未完结)

时间:2024-11-18 21:41:30浏览次数:1  
标签:le 未完结 int 电影 NFLS leq dp CD DP

录制唱片

你刚刚继承了流行的 “破锣摇滚” 乐队录制的尚未发表的 \(N\)(\(1\leq N\leq 20\))首歌的版权。你打算从中精选一些歌曲,发行 \(M\)(\(1\leq M\leq 20\))张 CD。每一张 CD 最多可以容纳 \(T\)(\(1\leq T\leq 20\))分钟的音乐,一首歌不能分装在两张 CD 中。CD 数量可以用完,也可以不用完。

不巧你是一位古典音乐迷,不懂如何判定这些歌的艺术价值。于是你决定根据以下标准进行选择:

  • 1.歌曲必须按照创作的时间顺序在所有的 CD 盘上出现。(注:第 \(i\) 张盘的最后一首的创作时间要早于第 \(i+1\) 张盘的第一首)

  • 2.选中的歌曲数目尽可能地多。



f[i][j][k]表示第i个CD,现在取到了第j首歌,此CD已存k分钟的歌了。

for(int i=0;i<m;i++){
    //枚举CD
		for(int j=1;j<=n;j++){
        //枚举所选的歌
			for(int k=0;k+a[j]<=t;k++){
            //枚举此CD已经存了多少分钟
				for(int l=j-1;l>=0;l--){
                //枚举上一个CD取到了哪
					for(int c=0;c<=t;c++){
						f[i+1][j][k+a[j]]=max(f[i+1][j][k+a[j]],f[i][l][c]+1);
					}
                    //第一种情况,这个CD还没用过。
					f[i+1][j][k+a[j]]=max(f[i+1][j][k+a[j]],f[i+1][l][k]+1);
                    //第二种情况,这个CD已用了k分钟。
					ss=max(ss,f[i+1][j][k+a[j]]);
                    //时刻更新最大值。
				}
			}
		}
	}

路短最

你可以通过许多的算法找到从一个地方到另外一个地方的最短路径。人们在他们的车上安装 GPS 设备然后他们的手机告诉他们最快的到达目的地的方式。然而,当在假期时,Troy 喜欢慢慢旅游。他想找最长的到目的地的路径以便他可以在路途中看许多新的以及有趣的地方。

因此,一个有效的路径包含一个不同城市的序列 \(c_1,c_2,...,c_k\),并且对于每个 \(1\le i<k\),有道路从 \(c_i\) 通往 \(c_{i+1}\)。

他不想重复访问任何城市,请帮他找出最长路径。

对于 \(100\%\) 的数据,有 \(2\le n \le 18,\) \(1\le m \le n^2-n,\) \(0\le s,d \le n-1,\) \(s\neq d,\) \(1\le l\le 10000\)。

明显可以状压,把每个城市的访问状态压到一位,Fij存i状态时在j城市的最长路。

Cloakroom

有 \(n\) 件物品,每件物品有三个属性 \(a_i, b_i, c_i\ (a_i<b_i)\)。注意输入顺序为 \(c_i, a_i, b_i\)。

再给出 \(q\) 个询问,每个询问由非负整数 \(m, k, s\) 组成,问是否能够选出某些物品使得:

  1. 对于每个选的物品 \(i\),满足 \(a_i\le m\) 且 \(b_i>m+s\)。
  2. 所有选出物品的 \(c_i\) 的和正好是 \(k\)。

\(1\le n\le 1000\),\(1\le a_i<b_i\le 10^9\),\(1\le c_i\le 1000\)。

\(1\le q\le 10^6\),\(1\le m\le 10^9\),\(1\le k\le 10^5\),\(0\le s\le 10^9\)。

把询问离线下来,把物品按a排序,询问按m排序。Fk表示当前考虑的物品c和恰好为k时的b被最大化的最小值。

image
神仙状态,反正我想不出来。

#include<bits/stdc++.h>
#define int long long
#define inf 9000000000000000000
using namespace std;
struct S{
	int a, b, c;
} a[1050];
constexpr int maxn = 2e6+10;
struct Q{
	int m, k, s, i;
} q[maxn];
int n, m, f[maxn];
bool b[maxn];
bool cmp1(S x, S y) { return x.a < y.a; }
bool cmp2(Q x, Q y) { return x.m < y.m; }
signed main(){
	scanf("%lld", &n);
	for (int i = 0; i < n; ++i)
		scanf("%lld%lld%lld", &a[i].c, &a[i].a, &a[i].b);
	
	sort(a, a + n, cmp1);
	scanf("%lld", &m);
	for (int i = 0; i < m; ++i)
		scanf("%lld%lld%lld", &q[i].m, &q[i].k, &q[i].s), q[i].i = i;
	
	sort(q, q + m, cmp2);
	f[0] = inf;
	for (int i = 0, j = 0; i < m; ++i){
		for (; j < n && a[j].a <= q[i].m; ++j)
			for (int l = 1e5; l >= a[j].c; --l)
				f[l] = max(f[l], min(f[l - a[j].c], a[j].b));
		
		b[q[i].i] = f[q[i].k] > q[i].m + q[i].s;
	}
	for (int i = 0; i < m; ++i)
		puts(b[i] ? "TAK" : "NIE");
	return 0;
}

奶牛看电影

奶牛贝西想连续看 \(L\)(\(1 \le L \le 10^8\))分钟的电影,有 \(N\)(\(1 \le N \le 20\))部电影可供选择,每部电影会在一天的不同时段放映。

贝西可以在一部电影播放过程中的任何时间进入或退出放映厅。但她不愿意重复看到一部电影,所以每部电影她最多看到一次。她也不能在看一部电影的过程中,换到另一个正在播放相同电影的放映厅。

请帮贝西计算她能够做到从 \(0\) 到 \(L\) 分钟连续不断地观看电影,如果能,请计算她最少看几部电影就行了。

一眼状压,发现不会了。
考虑看题解
状态是1e6的,显然压不进去别的东西了,而且最优解已经在状态里了。
所以我们dp里存另一个要最优化的东西。Fi表示状态为i时最晚的结束时间,我们要最化这个东西。显然转移的时候可以二分到没有空隙的最近一场即将开始的电影一定是最优的。

#include <bits/stdc++.h>
using namespace std;
const int N = 25;
int n, l, d[N], c[N][1005], dp[(1 << 20) + 5], popcnt[(1 << 20) + 5];

int main() {
    cin >> n >> l;
    for (int i = 1; i <= n; i++) {
        cin >> d[i];
        cin >> c[i][0];
        for (int j = 1; j <= c[i][0]; j++) cin >> c[i][j];
    }
    for (int i = 1; i < (1 << n); i++) dp[i] = -1;
    for (int i = 1; i < (1 << n); i++) popcnt[i] = popcnt[i >> 1] + (i & 1);
    for (int i = 0; i < (1 << n); i++) {
        if (dp[i] < 0)
            continue;
        for (int j = 1; j <= n; j++) {
            if (!(i & (1 << j - 1))) {
                int lst = upper_bound(c[j] + 1, c[j] + c[j][0] + 1, dp[i]) - c[j] - 1;
                if (lst != 0 && c[j][lst] + d[j] > dp[i])
                    dp[i | (1 << j - 1)] = max(dp[i | (1 << j - 1)], c[j][lst] + d[j]);
            }
        }
    }
    int ans = 0x3f3f3f3f;
    for (int i = 0; i < (1 << n); i++) {
        if (dp[i] >= l) {
            ans = min(ans, popcnt[i]);
        }
    }
    if (ans > n)
        puts("-1");
    else
        printf("%d", ans);
    return 0;
}

[BZOJ1399]Win

win 世界乒乓球比赛马上要拉开帷幕,你被邀请成为组委会成员,并且负责安排比赛赛程。

比赛采取淘汰赛赛制,失败的一方将被直接淘汰。

你手上现在有一份各个队员近期的战况,战况包含任意两名队员的最近一次交手结果。你默认这份对战结果将代表比赛的结果。

现在,你的好友要参加乒乓球比赛,你需要帮好友算一下,你可以安排出多少种淘汰赛赛程使得你的这位好友能够拿到最终的冠军。

当然,介于比赛的公平性,赛程的安排需要遵循这个原则,那就是使得淘汰赛的赛程树高度最低,也就是说,使得每位选手打的比赛数尽量平均。

状压dp,dp[u][s][d]表示集合为s,胜者为u,高度不超过d的方案数。转移的时候枚举u所在的集合。

Coci2009 podjela

有 \(n\) 个农民,他们住在 \(n\) 个不同的村子里,这 \(n\) 个村子形成一棵树,每个农民初始时有 \(x\) 元钱。
每一次操作,一个农民可以从它自己的钱中,取出任意数量的钱,交给某个相邻村子的农民。
对于每个农民给定一个值 \(v_i\),求最少需要多少次操作,使得每个农民最终拿到的钱 \(\geq\) 给定的值。



对于 \(100\%\) 的数据,\(1 \leq n \leq 2000,~0 \leq x \leq 10000,~\sum\limits_{i=1}^{n}v_i \leq n\times x\)

首先,简化为每个人有x-v元,要使所有人的钱数大于零。
钱数可以看作在树上流动,钦定一个节点为根,就要其他节点把钱都流向根节点。为什么只向根节点流呢?因为流的钱数可以是负的。设 DPi,j表示在以 i 为根的子树中,操作次数为 k 时的最大堆积钱数。子节点目前钱数是负的时候必须流动。
有一个临时数组转移有点难理解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2005;
int n,x,v[N],size[N],dp[N][N],f[N];
struct node{
	int to[N<<1],next[N<<1],tot,head[N];
	void adde(int u,int v){
		to[++tot]=v,next[tot]=head[u],head[u]=tot;
	}
}S;
void dfs(int u,int fa){
	dp[u][0]=v[u],size[u]=1;
	for (int i=S.head[u];i;i=S.next[i]){
		int v=S.to[i];
		if (v!=fa){
			dfs(v,u);
			for (int j=size[u]-1;j>=0;j--){//f先临时存一下对应操作次数的最优解(当背包理解)
				for (int k=size[v];k>=0;k--){
					f[j+k+1]=max(f[j+k+1],dp[v][k]+dp[u][j]);
					if (dp[v][k]>=0) f[j+k]=max(f[j+k],dp[u][j]);
				}
			}
			size[u]+=size[v];
			for (int j=0;j<=size[u];j++)
				dp[u][j]=f[j],f[j]=-1e9;
		}
	}
}
inline int read(){int x;cin>>x;return x;}
signed main(){
	cin>>n>>x;
	for (int i=0;i<=n+2;i++)
		for (int j=0;j<=n+2;j++)
			dp[i][j]=-1e9;
	for (int i=0;i<=n+2;i++) f[i]=-1e9;
	for (int i=1;i<=n;i++) v[i]=x-read();
	for (int i=1;i<n;i++){
		int u, v;
		cin>>u>>v;
		S.adde(u,v),S.adde(v,u);
	}
	dfs(1,0);
	for (int i=0;i<=n;i++)
		if (dp[1][i]>=0){
			cout<<i<<'\n';
			return 0;
		}
	return 0;
}

标签:le,未完结,int,电影,NFLS,leq,dp,CD,DP
From: https://www.cnblogs.com/Kang-shifu/p/18553748

相关文章

  • NFLS 图论题单笔记(完结)
    John的农场是一张N*N的方格图,贝茜住在左上角(1,1),John住在右下角(N,N)。现在贝茜要去拜访John,每次都只能往四周与之相邻的方格走,并且每走一步消耗时间T。同时贝茜每走三步就要停下来在当前方格吃草,在每个方格吃草的用时是固定的,为H[i][j]。John想知道贝茜最少要多久才能到达Joh......
  • Linux 下网络套接字(Socket) 与udp和tcp 相关接口
    文章目录1.socket常见API2sockaddr结构体及其子类1.sockaddr结构体定义(基类)2.子类sockaddr_in结构体用于(IPv4)3子类sockaddr_un(Unix域套接字)4.总结画出其结构体3.实现一个简单的tcpEcho服务器和客户端(cpp)3.1客户端3.2服务器3.3测试结果1.socket常......
  • 随机生成LDPC码并类下三角简化编码
    %function[H]=genH(rows,cols)%************设置参数***************rows=8;cols=24;u=[11010001110011011];%**********创建一个1*12的全为零的数组row_flag*******%**********创建一个24*12的全为零的矩阵parity_check**row_flag(1:rows)=0;parity_......
  • 线段树优化DP
    dp,即动态规划中有一类很重要的优化,叫做线段树优化。本文将介绍几种常见的类型及其套路和一些例题。前置知识:线性dp、线段树。权值线段树优化dp此类题目的dp转移通常和数值的大小关系有关,以下将介绍几道权值线段树优化DP题。CF597CSubsequences给定一个\(1\simn......
  • LaTeX教材排版-03:OptionsAndPackages.tex文件说明
    LaTeX教材排版-03:OptionsAndPackages.tex文件说明Latex教材OptionsAndPackages.tex这个文件的作用有两个,一个是自定义了一些文类的选项,根据这些选项做对应的设置,包括调用Book文类等;一个是导入需要用到的宏包。文件内容如下:\newif\ifistwoside\istwosidefalse\DeclareOption{t......
  • 【tokenization分词】WordPiece, Byte-Pair Encoding(BPE), Byte-level BPE(BBPE)的原
    目录前言1、word(词粒度)2、char(字符粒度)3、subword(子词粒度)WordPieceByte-PairEncoding(BPE)Byte-levelBPE(BBPE)总结前言Tokenization(分词)在自然语言处理(NLP)的任务中是最基本的一步,将文本处理成一串tokens用于后续的处理,把文本处理成token有一系列的......
  • DP学习总结
    动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。-----OIWiki例.1-最大子段和分析DP四步⑴定义状态定义\(dp_i\)表示以\(i\)结尾的最大子段和⑵分析答案答案即\({\max}^{i\in[1,n]}_{dp_i}\)⑶分析方程对于每个\(i\):可以与\([1,i-1......
  • 【未完结】 AtCoder Beginner Contest 380 题解
    AtCoderBeginnerContest380Rated:\(770\)A-123233简单模拟B-HurdleParsing字符串模拟C-MoveSegment找到第\(k\)个块的下标,模拟。D-StrangeMirroringE-1DBucketToolF-ExchangeGameG-AnotherShuffleWindow......
  • QObject,QMainWindpw,QWidget,QDialog介绍
    QObjectQObject的角色和特点在Qt框架中,QObject是整个对象模型的核心基类,它为Qt对象树和信号-槽机制提供了基础支持。很多Qt的类(包括QWidget、QDialog、QMainWindow)都直接或间接继承自QObject。QObject的核心功能对象树管理(ObjectTree)QObject提供了父子关......
  • 网络编程-002-UDP通信
    1.UDP通信的简单介绍1.1不需要通信握手,无需维持连接,网络带宽需求较小,而实时性要求高1.2包大小有限制,不发大于路径MTU的数据包1.3容易丢包1.4可以实现一对多,多对多2.客户端与服务端=发送端与接收端代码框架收数据方一般都是客户端/接收端3.头文件#include<arpa/ine......