首页 > 其他分享 >P1941-DP【绿】

P1941-DP【绿】

时间:2024-02-14 16:55:06浏览次数:41  
标签:输出 cout int tu DP P1941 tans dp

题目本身只是一道有些难度的普通dp题,题解中有人说可以把这个看作是背包,我不是这么做的便没细看,感觉能把他联想为背包问题的特例的人的发散思维能力真强。不过倒也没必要,常规做即可,用二维数组即可描述状态,dp[i][j]表示只由前i个横向单位长度组成的游戏中以(i,j)结尾游戏所需的最小游戏次数

然后注意读题,别理解错题意即可,遇到大部分AC小部分WA的局面就可视化输出排错即可,比如直接反过来输出dp数组从而使得输出的样子仿若游戏画面,上是上,下是下。正着输出反而没有这个效果。

但这都不重要,重要的是发现了一个非常奇特的事情,最终输出结果的时候,写成code1就最长0.98sAC了,写成code2就有少量点1.2s+TLE了
code1

cout<<1<<endl;
cout<<ans<<endl;

code2

cout<<1<<endl<<ans<<endl;

Amazing!!!
明明这段代码这运行了一次,却足足让耗时增加了0.2s,这太不可思议了,简直不合理。
我对这个的理解是,cout输出非endl对象和输出endl对象都可以返回cout对象,但是由于输出endl而返回的cout对象如果用于输出就会大大增加耗时。
但这个说法也不是很靠谱,因为我又试了printf,不论分两行输出还是分一行输出,都TLE了
所以我怀疑,是分行输出的cout莫名其妙特别对编译器的胃口,在O2优化的过程中产生了绝妙的优化效果。
但还是不是很靠谱,毕竟就是一个cout,再慢能有多慢?0.2s?荒谬
所以这是为什么呢?简直灵异事件了属于是。
紧接着,更灵异的事情出现了!!!!
我用之前AC的代码去重复提交,结果TLE了!!!又重复提交,又AC了...拿着TLE的代码反复提交也突然就AC了?!!!
离谱
这是虽然离谱,但是我却由此得到了这个问题的答案。

答案就是:这是一次“鸡误以为太阳是被自己叫起来”的事件。输出方式是什么根本不重要,具体能不能过可能取决于洛谷评测机算力的忽上忽下,也可能取决于同一代码不同时刻O2优化有着细微不同导致效率忽上忽下。第一个情况的可能性最大,第二个情况可能性不大,毕竟是同一个编译系统,理应没什么O2优化在不同时刻的不同。

因此只不过是洛谷评测机算力忽上忽下导致的,恰好和我关于cout输出方式的假设碰巧一致了,才导致了这个荒谬的结果。

Code

#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
#pragma GCC optimize (2) 
using namespace std;
struct tune{int b,t;}tu[10005];
int u[10005],d[10005],b[10005],n,m,k,x;
int dp[10002][1002];
signed main()
{
	//dp[i][j]表示只由前i个横向单位长度组成的游戏中以i,j结尾游戏所需的最小游戏次数
	//thus dp[i][j]= _1if i has a tune and j is alive or i hasn't a tune :
			//if dp[i-1][j+d[i-1]]!=-1,dp=dp[i-1][j+d[i-1]], else if dp[i-1][j-u[i-1]]!=-1,dp=1+dp[i-1][j-u[i-1]] ,else dp=-1
	//_2if i has a tune and j is die thus dp[i][j]=-1
	//-1 means unattachable
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>m>>k;
	for(int i=0;i<=n-1;i++)
		cin>>u[i]>>d[i];
	for(int i=1;i<=k;i++)
	{
		cin>>x;
		cin>>tu[x].b>>tu[x].t;//only between bottom and top can be alive
		b[x]=1;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m-1;j++)
		{
			if(b[i]==1&&(j<=tu[i].b||j>=tu[i].t))dp[i][j]=-1;
			else
			{
				int tans=99999999,jj=j;
				if(j+d[i-1]<=m&&dp[i-1][j+d[i-1]]!=-1)
					tans=min(tans,dp[i-1][j+d[i-1]]);
				for(int p=1;j-u[i-1]>=1;p++)
				{
					if (dp[i-1][j-u[i-1]]!=-1)
						tans=min(tans,p+dp[i-1][j-u[i-1]]);
					j-=u[i-1];
				}
				if(tans!=99999999) dp[i][jj]=tans;
				else dp[i][jj]=-1;
				j=jj;
			}
		}
		int j=m;
		if(b[i]==1&&(j<=tu[i].b||j>=tu[i].t))dp[i][j]=-1;
		else
		{
			int tans=99999999,jj=j,p;
			for(p=1;j-u[i-1]>=1;p++)
			{
				if(dp[i-1][m]!=-1)
					tans=min(tans,1+dp[i-1][m]);
				for(int k=j-u[i-1];k<=j-1;k++)
					if(dp[i-1][k]!=-1)
						tans=min(tans,p+dp[i-1][k]);
				j-=u[i-1];
			}
			for(int k=1;k<=j-1;k++)
				if(dp[i-1][k]!=-1)
					tans=min(tans,p+dp[i-1][k]);
			if(tans!=99999999) dp[i][jj]=tans;
			else dp[i][jj]=-1;
		}
	}
	int ans=99999999;
	for(int j=1;j<=m;j++)
		if(dp[n][j]!=-1)
			ans=min(ans,dp[n][j]);

	if(ans!=99999999)
	{
		cout<<1<<endl<<ans<<endl;
	}
	else
	{
		for(int i=n;i>=1;i--)
		{
			int tf=0;
			for(int j=1;j<=m;j++)
			{
				if(dp[i][j]!=-1)
				{
					tf=1;
					break;
				}	
			}
			if(tf==1)
			{
				ans=0;
				for(int ii=1;ii<=i;ii++)
					if(b[ii]==1)
						ans++;
				cout<<0<<endl<<ans<<endl;
				break;
			}
		}
	}
	/*
	cout<<endl<<endl;
	for(int j=m;j>=1;j--)
	{
		for(int i=1;i<=n;i++)
		{
			printf("%4d",dp[i][j]);
		}
		cout<<endl;
	}*/
	return 0;
}

标签:输出,cout,int,tu,DP,P1941,tans,dp
From: https://www.cnblogs.com/gongkai/p/18015302

相关文章

  • 数位 DP 做题记录
    数位DP数位DP的常见套路就是记录当前到哪一位,是否抵着上界,转移时枚举当前可以填哪些数,做一遍记忆化搜索。P3413SAC#1-萌数题意:求\([l,r]\)中有多少个数中含有回文子串。思路:如果存在回文子串,那么必然有相邻两位相同或者间隔一位相同,在数位DP时额外记录前2位就可以......
  • Codeforces Round 113 (Div. 2)E. Tetrahedron(dp、递推)
    目录题面链接题意题解代码总结题面链接E.Tetrahedron题意从一个顶点出发走过路径长度为n回到出发点的方案总数题解考虑dp\(f[i][0|1|2|3]\):走了i步,现在在j点的方案总数转移:\(f[i][0]=f[i-1][1]+f[i-1][2]+f[i-1][3]\)\(f[i][1]=f[i-1][0]+f[i-1][2]+f[i-1][3]\)\(f......
  • Atcoder Educational DP Contest 题解
    比赛链接:Atcoderr或者题单A:Frog1常规线性dp,注意到对于每个落点来说,青蛙只能由第\(i-1\)个石头或者第\(i-2\)个石头转移得到,那么我们让\(dp[i]\)为当跳到第\(i\)个石头上的最小费用。此时显然有:\[dp_i=\min(dp_{i-1}+\left|h_i-h_{i-1}\right|,dp_{i-2}+\left|h_......
  • 【Java 并发】【队列应用】【二】Tomcat的NioEndPoint中ConcurrentLinkedQueue 的使用
    1 前言这一节我们讲解Tomcat的NioEndPoint中ConcurrentLinkedQueue的使用。2  Tomcat的容器结构本节讲解apache-tomcat-7.0.32-src源码中ConcurrentLinkedQueue的使用。首先介绍Tomcat的容器结构以及NioEndPoint的作用,以便后面能够更加平滑地切入话题,如图11-4所示......
  • POJ--1179 Polygon(区间DP)
    记录22:012024-2-10http://poj.org/problem?id=1179区间DP问题。区间DP问题可能需要注意的点就是是根据区间长度来计算的,随着迭代区间长度不断增加,结果也就计算出来了这种“任意选择一个位置断开,复制形成2倍长度的链”的方法,是解决DP中环形结构的常用手段之一因此读入数......
  • JMeter 进行UDP压力测试
    第一步:安装udp插件第二步:添加线程组,然后按下添加UDP请求设置如下配置你要测试的服务器IP和端口。按照下面的格式输入16进制数数据然后可以开始跑了......
  • Codeforces Round 260 (Div. 1)A. Boredom(dp)
    最开始写了一发贪心wa了,然后这种选和不选的组合优化问题,一般是考虑动态规划\(dp[i][0]:\)表示第i个数不选的最大值\(dp[i][1]:\)表示第i个数选的最大值考虑转移:\(dp[i][0]=max(dp[i-1][1],dp[i-1][0])\)\(dp[i][1]=dp[i-1][1]+a[i]*i\)需要将每一个数用一个桶统计次数因......
  • 基于Huggingface Accelerate的DDP训练
    #-*-coding:utf-8-*-""""ThisdocumentisasimpleDemoforDDPImageClassification"""fromtypingimportCallablefromargparseimportArgumentParser,Namespaceimporttorchfromtorch.backendsimportcudnnfro......
  • 单调队列优化DP&斜率优化&四边形不等式
    在本文中,我们将通过一道题来浅谈DP优化三大妈。P3195[HNOI2008]玩具装箱-洛谷|计算机科学教育新生态(luogu.com.cn)对于这种类型的题目,我们一般可以转化为如下形式:那么,$val(i,j)$又通常分为两种情况:其值仅与$i,j$中的一个有关。其值与$i,j$两者都有关。单调队列......
  • Java之UDP,TCP的详细解析
     练习四:文件名重复publicclassUUIDTest{publicstaticvoidmain(String[]args){Stringstr=UUID.randomUUID().toString().replace("-","");System.out.println(str);//9f15b8c356c54f55bfcb0ee3023fce8a}}```publicclassClient{public......