题意:求下面式子的最小值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;
}