codeforces 1300E Water Balance

題目地址

思維

#include<bits/stdc++.h>
#define pk push_back 
using namespace std;
typedef long long ll;
double dp[1000010],sum[1000010];
int main()
{
	int n,x;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>x,dp[i]=x,sum[i]=sum[i-1]+dp[i];//前綴和 便於計算區間和
	for(int i=2;i<=n;i++)
	{
	    double cnt=dp[i];
		for(int j=i-1;j>=1;j--) //找到一個 低點
		{
			if(dp[j]>cnt)
			{
				cnt=(sum[i]-sum[j-1])/(i-j+1); 新區間平均值
				if(j==1)
				for(int k=j;k<=i;k++)
				dp[k]=cnt;  //區間更新
			}
			else
			{
				for(int k=j+1;k<=i;k++)
				dp[k]=cnt;  // 區間更新
				break;
			}
		}
	}
	for(int i=1;i<=n;i++)
	printf("%.9lf\n",dp[i]);
	return 0;
}

上面的代碼妥妥TLE 所以我可以可以優化 區間更新和查找低點的過程

如下

#include<bits/stdc++.h>
#define pk push_back 
using namespace std;
typedef long long ll;
double sum[1000010];
int x[1000010];
struct node
{
	int l,r;  // 區間[l,r]  
	double w;  //區間平均值
};
vector<node> a; // 任意一個線性結構
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cin>>x[i],sum[i]=sum[i-1]+(double)x[i];
	a.pk((node){1,1,(double)x[1]});
	for(int i=2;i<=n;i++)
	{
		double cnt=(double)x[i];
		int l=i;
		for(int j=a.size()-1;j>=0;j--)
		{
			if(a[j].w>=cnt)
			{
				l=a[j].l;
				cnt=(sum[i]-sum[l-1])/(i-l+1);
				a.pop_back(); // 當前節點刪去
				if(j==0)
				{
					a.pk((node){1,i,cnt});   // 新區間更新 變成了更新一個節點
					break;
				}
			}
			else
			{
				a.pk((node){l,i,cnt});
				break;
			}
		}
	}
	for(int i=0;i<a.size();i++)
	{
		for(int j=a[i].l;j<=a[i].r;j++)
		printf("%.9lf\n",a[i].w); 輸出區間
	}
	a.clear();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章