WEEK 1 DAY 4

题意:求下面式子的最小值b未知:

思路:a[i]-i当做新的a[i],用中位数定理,一个点到n个点的距离和最小是他们的中位数

一看到绝对值,就应该想到数轴上点之间的距离,这道题虽然给b加上了i,但只要把式子拆开,一开始就把每个Ai减去i就行了。然后可以证明(或者学过)一个点到其他点距离和最短应该是这些点坐标集合的中位数,
#include<bits/stdc++.h>
using namespace std;
#define int long long

int a[200006];
signed main(){
	int n,k;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]=a[i]-i;
	}
	sort(a+1,a+1+n);
	int ans=LLONG_MAX;
	int mi=n/2;
	int b[4]={a[mi],a[mi+1],a[mi-1]};
	for(int i=0;i<=2;i++){
		int res=0;
		for(int j=1;j<=n;j++){
			res+=abs(a[j]-b[i]);
		}
		ans=min(ans,res);
	}
	cout<<ans<<endl;
	return 0;
}

2024 暑假友谊赛-热身1 - Virtual Judge

给定一个代价矩阵C,在给定一个矩阵a,要求将此矩阵a中的所有元素都变为1,将i变成j,代价是c[i][j];用弗洛伊德算法求最短路即可,算出每一个点到1的最短距离即最短代价:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int c[10][10];
int ans[10][10];
int a[260][280];
//priority_queue<int,vector<int>,greater<int>>a;
signed main(){
	int h,w;//h是行数,w是列数;
	cin>>h>>w;
	for(int i=0;i<=9;i++){
		for(int j=0;j<=9;j++){
			cin>>c[i][j];
		}
	}
	int sum=0;
//	int fu=0;
	//int minn=0;
	for(int k=0;k<=9;k++){
		for(int j=0;j<=9;j++){
			for(int i=0;i<=9;i++){
				c[i][j]=min(c[i][j],c[k][i]+c[j][k]);
			}
		}
	}
	//for(int i=0;i<=9;i++)minn=min(minn,c[i][1]);
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			cin>>a[i][j];
			 if(a[i][j]!=-1){
				sum+=c[a[i][j]][1];
			}
		}
	}
	cout<<sum<<endl;
	return 0;
}

 找到一的位置,然后选中剩下的(k-1)个数框住它,让它们都变为1,除去一本身,则总共有n-1个数,除去框中唯一且一定存在的一,框中还有k-1,个数,所以最小操作数是n-1/k-1,向上取整:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int b[100006];
int a[100006];
signed main(){
	int n,k;
	cin>>n>>k;
		if((n-1)%(k-1)==0)cout<<(n-1)/(k-1)<<endl;
		else cout<<(n-1)/(k-1)+1;
		
	

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值