列表

详情


NC205081. 不平衡数组

描述

给定一个长度为 n 的数组。要求相临的数大小不相同,假如相临数的相同,
你可以通过将 a[i]+1 来改变它的大小,但是需要付出 b[i]的代价,同时对于每
个 a[i]只能加一次。问你付出的最小代价。

输入描述

第 1 行 1 个整数 n,表示数组长度为 n
接下来 n 行,每行 2 个正整数 a[i]与 b[i],表示 a 数组中的第 i 个数,以及将第 i 个数+1 的代价。
对于20%的数据,保证b[i] = 1
对于另外10%的数据,保证所有a[i]相等
对于另外10%的数据,保证所有的a[i]不相等
对于100%的数据,1<=n<=2e5,0<=a[i]、b[i]<=1e9

输出描述

1 行,一个数字 ans,表示最小代价。

示例1

输入:

4
1 2
2 2
2 3
4 1

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 144ms, 内存消耗: 6748K, 提交时间: 2020-06-05 23:37:53

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+1000;
ll a[N],b[N];
ll f[N][2];
int n;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
	memset(f,0x3f,sizeof f);
	f[1][0]=0;f[1][1]=b[1];
	for(int i=2;i<=n;i++)
	{
		if(a[i]!=a[i-1]) f[i][0]=min(f[i][0],f[i-1][0]);
		if(a[i]!=a[i-1]+1) f[i][0]=min(f[i][0],f[i-1][1]);
		if(a[i]+1!=a[i-1]) f[i][1]=min(f[i][1],f[i-1][0]+b[i]);
		if(a[i]+1!=a[i-1]+1)f[i][1]=min(f[i][1],f[i-1][1]+b[i]);
	}
	cout<<min(f[n][0],f[n][1])<<endl;
	
} 

C++11(clang++ 3.9) 解法, 执行用时: 85ms, 内存消耗: 6804K, 提交时间: 2020-07-06 18:53:00

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
typedef long long ll;
ll a[N],b[N];
int main()
{
	scanf("%d",&n);
	ll ans=0;
	for(int i=1;i<=n;i++)
	scanf("%lld%lld",&a[i],&b[i]);
	for(int i=1;i<=n;i++)
	{
		if(a[i]==a[i-1])
		{
			int l=i-1,r;
			while(a[i]==a[i-1])i++;
			r=i-1;
			ll c1=0,c2=0;
			for(int j=l;j<=r;j+=2)
			c1+=b[j];
			for(int j=l+1;j<=r;j+=2)
			c2+=b[j];
			ans=ans+min(c1,c2);
		}
	}
	printf("%lld\n",ans);
	return 0;
}

Python3(3.5.2) 解法, 执行用时: 719ms, 内存消耗: 15060K, 提交时间: 2020-06-05 19:51:40

n=int(input())
a=[]
b=[]
for i in range(n):
    x,y=map(int,input().split())
    a.append(x)
    b.append(y)
ans=0;l=0;r=1
while l<n:
    while r<n and a[l]==a[r]:r+=1
    if r-l>1:
        s1=0
        for i in range(l,r,2):s1+=b[i]
        s2=0
        for j in range(l+1,r,2):s2+=b[j]
        ans+=min(s1,s2)
    l=r;r+=1
print(ans)

上一题