//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题意:给出2n个数,将其中n个向下取整,剩下n个向上取整,要使操作之后的数之和和操作之前的数之和的差值最小,问最小差值。
题解:很明显只和小数部分有关,那么我们把有小数部分的数的小数部分提取出来。排序,选择前k小向下取整,维护一个最小的ans。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=4005;
double a[N];
int main() {
int n;
while(~scanf("%d",&n)) {
int m=0;
double x,det=0;
for(int i=1;i<=2*n;++i) {
cin>>x;
int xx=x;
if(x-(double)xx>0.0001) {
a[++m]=x-(double)xx;
det+=x-(double)xx;//加上实数部分
}
}
sort(a+1,a+1+m);
double ans=fabs(det-(m-max(0,m-n)));
int tt=min(m,n);
for(int i=max(0,m-n)+1;i<=tt;++i) {//i个向下取整的
double t=fabs(det-(m-i));
ans=fmin(ans,t);
}
printf("%.3lf\n",ans);
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=3005;
int a[N];
int main() {
int n;
while(~scanf("%d",&n)) {
int cnt=0;
for(int i=1;i<=n;++i) {
scanf("%d",&a[i]);
for(int j=1;j<i;++j) {
if(a[j]>a[i]) ++cnt;
}
}
if(cnt==0) {
puts("0.000000");
} else if(cnt&1) {
printf("%d.000000\n",2*cnt-1);
} else {
printf("%d.000000\n",2*cnt);
}
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if(j+1≤n) d[k][i][j]=min(d[k][i][j],d[k][i-1][j+1]+b[i]);
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define de(x) cout << #x << "=" << x << endl
const int N=25;
ll a[N],b[N],d[N][N][N];
int n,m;
struct Mat {
ll mat[N][N];
Mat() {memset(mat,0x3f,sizeof(mat));}
Mat operator * (Mat B) {
Mat C;
for(int i=0;i<=n;++i) {
for(int j=0;j<=n;++j) {
for(int k=0;k<=n;++k) {
C.mat[i][j]=min(C.mat[i][j],mat[i][k]+B.mat[k][j]);
}
}
}
return C;
}
};
Mat powmul(Mat A,int k) {
Mat B;
for(int i=0;i<=n;++i) B.mat[i][i]=0;
while(k) {
if(k&1) B=B*A;
A=A*A;
k>>=1;
}
return B;
}
Mat M;
int main() {
while(~scanf("%d%d",&n,&m)) {
for(int i=1;i<=n;++i) scanf("%I64d",&a[i]);
for(int i=1;i<=n;++i) scanf("%I64d",&b[i]);
memset(d,0x3f,sizeof(d));
for(int k=0;k<=n;++k) {
d[k][0][k]=0;
for(int i=1;i<=n;++i) {
for(int j=0;j<=n;++j) {
if(j-1>=0)
d[k][i][j]=min(d[k][i][j],d[k][i-1][j-1]+a[i]);
if(j+1<=n)
d[k][i][j]=min(d[k][i][j],d[k][i-1][j+1]+b[i]);
}
}
}
for(int i=0;i<=n;++i) {
for(int j=0;j<=n;++j) {
M.mat[i][j]=d[i][n][j];
}
}
printf("%I64d\n",powmul(M,m).mat[0][0]);
}
return 0;
}