友好的生物
【问题描述】W星球是一个和地球一样气候适宜、物种聚集的星球。经过多年的研究,外星生物学家们已经发现了数万种生物,而且这个数字还在不断增大。W星球上的生物很有趣,有些生物之间很友好,朝夕相伴,形影不离;但有些却很敌对,一见面就难免发生战斗。为了能够更好地了解它们之间的友好程度,外星生物学家希望进行一些量化的计算。他们发现,两种生物之间的友好程度和它们的K种属性有关,暂且将它们编号为属性\(1\)、属性\(2\)、……、属性\(K\),这些属性都是可以进行量化的。外星生物学家研究发现,如果前\(K-1\)种属性的差别越大,这两种生物就越友好;但是属性\(K\)与众不同,这种属性差别越小的两种生物越友好。因此他们猜想是不是可以用这样一个公式量化两种生物之间的友好程度:( 属性i的差别) CK 属性K的差别\(Friendliness=(\sum\limits_{i=1}^{K-1}属性i的差别)-C_K\times属性K的差别\),其中\(C_i\)是非负常数。如果知道了每种生物的各种属性,利用上述公式就很容易算出它们之间的友好程度了。现在,外星生物学家们想问一问:在目前发现的这些生物当中,关最友好的那对生物是哪一对呢?它们之间的友好程度是多少?
【输入文件】输入文件的第一行是两个整数\(N\)和\(K\),分别表示目前发现的生物种数和属性的种数。第二行有K个非负整数\(C_i\),即计算友好程度时所需的常数。接下来的\(N\)行,描述每种生物,按照先后顺序依次编号为生物\(1\)、生物\(2\)、……、生物\(N\)。每一行都有K个整数,给出该种生物的各项属性值,按照先后顺序依次编号为属性\(1\)、属性\(2\)、……、属性\(K\)。
【输出文件】输出文件包含一行,为一个整数,表示最友好的生物之间的友好程度。
【约定】
\(2 ≤ N ≤ 100,000\) \(2 ≤ K ≤ 5\) \(0 ≤ C_i ≤ 100\)
每种生物的各项属性值不小于\(-10000\)且不大于\(10000\)
最大的友好程度一定大于0
【样例输入】
5 3 1 2 3 -5 3 2 -2 3 0 0 5 9 3 4 -1 -10 -11 7
【样例输出】36
【样例说明】生物3和5之间的友好程度为\(1\times|0-(-10)|+2\times|5-(-11)|-3\times|9-7|=36\)
40昏
#include
using namespace std;
const int N=100000+5,M=150000+5,inf=0x3f3f3f3f,P=19650827;
int n,K,a[N][10];
double c[10],ans=0.0;
template
void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int main(){
freopen("species.in","r",stdin);
freopen("species.out","w",stdout);
rd(n),rd(K);
for(int i=1;i< = K;++i) scanf("%lf",&c[i]);
for(int i=1;i< = n;++i)
for(int j=1;j< = K;++j) rd(a[i][j]);
for(int i=1;i< = n;++i)
for(int j=i+1;j< = n;++j){
double sum=0.0;
for(int k=1;k < K;++k) sum+=c[k]*Abs(a[i][k]-a[j][k]);
if(sum < ans) continue;
sum-=c[K]*Abs(a[i][K]-a[j][K]);
ans=Max(sum,ans);
}
printf("%d",(int)ans);
return 0;
}
程姓男子的50昏
#include
using namespace std;
const int maxn=100005;
const int maxk=10;
template
void read(t &x)
{
int f=1;x=0;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*f;
}
int Abs(int a){return a>=0?a:-a;}
int Max(int a,int b) {return a>b?a:b;}
struct A
{
int k[maxk];
}a[maxn];
int n,k,c[maxk],ans,tmp;
void init()
{
freopen("species.in","r",stdin);
freopen("species.out","w",stdout);
}
void readdata()
{
read(n),read(k);
if(n>=50000)
{
printf("1840\n");
exit(0);
}
for(int i=1;i<=k;i++)
{
read(c[i]);
}
for(int i=1;i< = n;i++)
{
for(int j=1;j< = k;j++)
{
read(a[i].k[j]);
}
}
}
void work()
{
for(int i=1;i< = n;i++)
{
for(int j=1;j< i ; j++)
{
tmp=0;
for(int p=1;p < k ;p++)
{
tmp+=c[p]*(Abs(a[i].k[p]-a[j].k[p]));
}
ans=Max(tmp-c[k]*Abs((a[i].k[k]-a[j].k[k])),ans);
}
}
printf("%d\n",ans);
}
int main()
{
init();
readdata();
work();
return 0;
}
基因重组
\(nwt\)表示当前目标已经拼了多长 \(nws\)表示材料已经用了多长
因为它有可能是这一段正着拼后面一段又进行其它操作 所以一个一个地去做(超级暴力
超级暴力的20昏
using namespace std;
#define ll long long
#define rg register
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
const int N=5000+5,M=1e5+5,inf=0x3f3f3f3f,P=19650827;
int n,m,ans=inf,c1,c2,c3,a[N],b[N];
char s[N],t[N];
template
void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
void dfs(int nwt,int nws,int cos,int cz){
if(cos>=ans) return;
if(nwt==m){ans=Min(ans,cos);return;}
if(nws < n ) {
if(b[nwt+1]==a[nws+1]){
if(cz==1) dfs(nwt+1,nws+1,cos,1);
else dfs(nwt+1,nws+1,cos+c1,1);
}
if(b[nwt+1]==(a[nws+1]+(a[nws+1]%2?1:-1))){
if(cz==3) dfs(nwt+1,nws+1,cos,3);
else dfs(nwt+1,nws+1,cos+c1,3);
}
if(cz==2) dfs(nwt,nws+1,cos,2);
else dfs(nwt,nws+1,cos+c2,2);
}
dfs(nwt+1,nws,cos+c3,0);
}
int main(){
freopen("T2.txt","r",stdin);
// freopen("DNA.out","w",stdout);
rd(c1),rd(c2),rd(c3);
scanf("%s",s+1);scanf("%s",t+1);
n=strlen(s+1),m=strlen(t+1);
for(int i=1;i<=n;++i)
if(s[i]=='A') a[i]=1;
else if(s[i]=='T') a[i]=2;
else if(s[i]=='C') a[i]=3;
else if(s[i]=='G') a[i]=4;
for(int i=1;i<=m;++i)
if(t[i]=='A') b[i]=1;
else if(t[i]=='T') b[i]=2;
else if(t[i]=='C') b[i]=3;
else if(t[i]=='G') b[i]=4;
dfs(0,0,0,0);
printf("%d",ans);
return 0;
}
其实有做过一道类似的题 也是两个串 那个是直接的数字 操作也差不多 只是我忘了...
考试的时候想出来了状态的那个数组就是\(f[i][j][0/1/2]\)材料的前i个来拼目标的前j个操作是第1/2/3个
只是懒得想了...
危险的迷宫
我没有去复习网络流...前几天做匈牙利算法的时候我就该想到...可是我就是不想看
这个应该是边的数量达150以上就T了 \(10\times10\)最多就\(180\)条通路 所以暴搜选手必须要拥有姓名
只是我没有看到无解的情况下输出-1...(我还想到无解咋整啊 既然他没说那就铁定是保证有解 结果他说了我没看到)
80昏
#include
using namespace std;
#define ll long long
#define rg register
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)>(y)?(y):(x))
const int N=10+5,M=150000+5,inf=0x3f3f3f3f,P=19650827;
int A,B,n,k,ans=0,mp[N][N],st[1000],ed[1000],ided[N][N];
bool vis[150],ton[105][105];
template
void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int adr(int x,int y){return (x-1)*B+y;}
void dfs(int u,int sum,int cnt){
if(sum>=ans) return;
int xu=u/B+1,yu=u%B;
if(!yu) yu=B,--xu;
sum+=mp[xu][yu],vis[u]=1;
if(ided[xu][yu]){
++cnt;
if(cnt==n){ans=Min(ans,sum);return;}
dfs(st[cnt+1],sum,cnt);
}
else {
int v;
if(ton[u][v=u+B]&&!vis[v]) vis[v]=1,dfs(v,sum,cnt),vis[v]=0;
if(ton[u][v=u-1]&&!vis[v]) vis[v]=1,dfs(v,sum,cnt),vis[v]=0;
if(ton[u][v=u+1]&&!vis[v]) vis[v]=1,dfs(v,sum,cnt),vis[v]=0;
if(ton[u][v=u-B]&&!vis[v]) vis[v]=1,dfs(v,sum,cnt),vis[v]=0;
}
}
int main(){
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
rd(A),rd(B);ans=inf;
for(int i=1;i<=A;++i)
for(int j=1;j<=B;++j) rd(mp[i][j]);
rd(k);
for(int i=1,x,y,x1,y1,X,Y;i<=k;++i)
rd(x),rd(y),rd(x1),rd(y1),X=adr(x,y),Y=adr(x1,y1),ton[X][Y]=ton[Y][X]=1;
rd(n);
for(int i=1,x,y;i<=n;++i) rd(x),rd(y),st[i]=adr(x,y);
for(int i=1,x,y;i<=n;++i) rd(x),rd(y),ed[i]=adr(x,y),ided[x][y]=1;
dfs(st[1],0,0);
if(ans!=inf) printf("%d",ans);
else puts("-1");
return 0;
}
正解:网络流