首页 > 其他分享 >CodeTON Round 8 (Div. 1 + Div. 2, Rated, Prizes!) D

CodeTON Round 8 (Div. 1 + Div. 2, Rated, Prizes!) D

时间:2024-03-31 13:33:53浏览次数:28  
标签:Rated int read Prizes push Div dp 啊啊啊

链接

开始的时候看错题了。以为区间是可以我划分的,后面才发现是连着的区域是被强制合并的。
导致我第一个写了给k短路。紫砂了。

然后我的第二个思路是,从后往前和从前往后做两边dp,然后尝试枚举断点,看看有没有比最优稍微劣一点的解法。
然后样例就是反例。

正解是想到过的,但是因为时间复杂度被叉了。我觉得这个k和n应该是不能被同时记录在dp中的,然后就产生了上面的做法中的贪心,也就是前k短路应该都是由最短路改变而来的。
不然在我的认知里面,这题不可做。然后就wa在了test1。没过样例。

妈妈生的,为什么会觉得记录前k个答案会T啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
我在想什么。

正解就是设\(f[i]\)表示以\(i\)结尾(\(i\)不选)的前面的区间能够取到的前k个最大的答案。
然后转移其实就很简单,每次考虑前面的位置,先把每个位置\(f[j]\)的 第一个数字放入优先队列里面,然后就取里面最大的放到\(f[i]\)中,再把这个\(f[j]\)的下个位置入队。
满了k个就结束。

\(O((n+k)\times n \times log(nk))\)

很可以做啊。。。。
为什么。。我会把这个记录前k个答案的方法叉了。。
为什么。。。。
唉唉

可能因为前面没有做过类似的题目吧。。。
难绷。这真是太蠢了。。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
	char c=getchar();int a=0,b=1;
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int n,k,a[1001][1001];
vector<int> dp[1001];
int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--)
	{
		n=read();k=read();
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				a[i][j]=read();
			}
		}
		for(int i=0;i<=n;i++)
		{
			dp[i].clear();
		}
		dp[0].push_back(0);
		for(int i=1;i<=n;i++)
		{
			priority_queue<pair<int,pair<int,int> > > q;
			q.push({dp[i-1][0],{i-1,0}});
			for(int j=i-2;j>=0;j--)
			{
				q.push({dp[j][0]+a[j+2][i],{j,0}});
			}
			q.push({0+a[1][i],{-1,0}});
			while(q.size()!=0 && dp[i].size()<k)
			{
				int val=q.top().first;
				int j=q.top().second.first;
				int num=q.top().second.second;
				q.pop();
				dp[i].push_back({val});
				if(j<0||num+1==dp[j].size())continue;
				if(j==i-1)//Needn't create interval
				{
					q.push({dp[j][num+1],{j,num+1}});
				}
				else
				{
					q.push({dp[j][num+1]+a[j+2][i],{j,num+1}});
				}
			}
		}
		for(int i=0;i<k;i++)
		{
			cout<<dp[n][i]<<' ';
		}
		cout<<endl;
	}
	return 0;
}

标签:Rated,int,read,Prizes,push,Div,dp,啊啊啊
From: https://www.cnblogs.com/HLZZPawa/p/18106636

相关文章

  • codeforces div4 Double Strings
    #include<iostream>#include<algorithm>#include<cstring>#include<map>usingnamespacestd;intT,n;strings[900005];map<string,int>mm;//存放每一个字符串是否出现过intmain(){ cin>>T; while(T--){ mm.clear();//每次清空mm里面的数......
  • Codeforces Round 937 (Div. 4)----->E. Nearly Shortest Repeating Substring
    一,思路:1.这题很容易想到枚举n的因数(时间复杂度n^(1/2)),然后根据这个长度枚举字符串,看是否满足最多只有一个不相同(时间复杂度n)。总的时间复杂度是(n根号n)的级别。又n是1e5级别所以可以过。但是当n是1e6就不行了。2.难点在于如何判断,一个字符串的不同字符数量,主要是hshah......
  • Codeforces Round 936 (Div. 2)
    Preface懒狗闪总开完组会不打CF直接滚去睡觉了可海星,感觉我好像退化成我们队训练最少的人了赛后补了下发现这场题竟然都会做,不过F不知道是我实现有问题常数大得一批加了读优才惊险卡过A.MedianofanArray签到,找到中位数后面与它相同的数的个数即可#include<cstdio>#incl......
  • Codeforces Round 915 (Div. 2) D
    CyclicMEX题面翻译对于一个长为\(n\)的排列\(p\),定义其权值为\(\sum_{i=1}^n\operatorname{mex}_{j=1}^ip_j\),也就是\(p_1\simp_i\)中没有出现过的最小自然数的和。然后你可以对这个排列进行移位操作,问最大权值。题目描述Foranarray$a$,defineitscostas$......
  • Div4 VP总结
    CodeforcesRound799(Div.4)E(最长子区间)基本思路求满足s的最长子区间。错误思路分析想用双指针左右贪心模拟题目要求删前或后的数(但在面对前后两个相等的时候,删前删后没有无后效性)简单暴力枚举子区间长度(显然在n=1e5的时候t了)正确思路虽然也是暴力枚举子区间,但有做......
  • css实现弹出的div显示在屏幕中间
    主要代码如下:.info{width:90vw;height:102vw;display:block;position:fixed;z-index:999;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:14px;}.info-header{......
  • Windows Packet Divert(WinDivert)是一个适用于Windows 10、Windows 11和Windows Server
    WindowsPacketDivert(WinDivert)是一个适用于Windows10、Windows11和WindowsServer的用户模式数据包捕获和重定向工具。WinDivert允许用户模式应用程序捕获/修改/丢弃发送到/从Windows网络堆栈的网络数据包。总之,WinDivert可以:捕获网络数据包过滤/丢弃网络数据包嗅探......
  • Codeforces Round 936 (Div. 2) E
    SofiaandStrings题面翻译\(t\)组数据。每一次测试,有长度为\(n\)的序列\(s\),长度为\(m\)的序列\(t\)。你可以对\(s\)进行两种操作:删除\(s_i,1\lei\le|s|\)(\(s\)从\(1\)开始标号).将\(s_l,s_{l+1},\dots,s_r\)排序(\(1\lel\ler\le|s|\))。上面\(|s|......
  • CF1935 Codeforces Round 932 (Div. 2)
    C.MessengerinMAC给两个数组a,b和一个整数L.寻找一个关于a,b下标的序列p,使得\(\suma_{p_i}+\sum|b_{p_i}-b_{p_{i+1}}|\leqL\)SolutionKey1:按照b从小到大排序一定是最优的.Key2:固定\(b_l\),\(b_r\),那么\(\sum^r_l|b_{p_i}-b_{p_{i+1}}|=b_r-b_l......
  • codeforces div3 935
    Problem-E-Codeforces题解:一道二分糖题首先我们先在原序列跑一遍题目给的二分,然后跑出最后的l点我们稍微思考一下,这个l这个点一定小于或者等于x为什么呢一个在这个二分里,如果最后的点是大于x的那么必定被r拿走,因为判断上l只能接收比x小的地点所以我们知道l以后,要么就是l=......