usaco2017febgold总结

来源:互联网 发布:java加载配置文件 编辑:程序博客网 时间:2024/06/09 14:01

usaco2017febgold总结

Problem 1.为什么奶牛过马路1(visitfj)

题意

有一幅n*n的方格图,n <=100,每个点上有一个值。从(1,1)出发,走到(n,n),只能走上下左右。每走一步花费t,每走三步需要花费走完三步后到达格子的值。求最小花费的值。最短路径问题。

方法

用spfa解决,要拆点,dis[i][j]表示到达第i个点时走的总步数模3等于j时的最小花费值。

Problem 2. 为什么奶牛过马路II(nocross)

题意

上下有两个长度为n、位置对应的序列A、B,其中数的范围均为1~n。若abs(A[i]-B[j])<= 4,则A[i]与B[j]间可以连一条边。现要求在边与边不相交的情况下的最大的连边数量。n <= 10^4。

方法

用简单的最长公共连续子序列的DP方法来做。

CODE

#include<iostream>

#include<algorithm>

#include<cmath>

int n,a[1005],b[1005],f[1005][1005];

using namespace std;

int main()

{

   cin>>n;

   for (int i=1; i<=n; i++) cin>>a[i];

   for (int i=1; i<=n; i++) cin>>b[i];

       for(int i=1; i<=n; i++)

              for(int j=1; j<=n; j++)

              {

                     f[i][j]=max(f[i-1][j],f[i][j-1]);

                     if(abs(a[i]-b[j])<=4) f[i][j]=max(f[i][j],f[i-1][j-1]+1);

              }    

       cout<<f[n][n]<<endl;

return 0;

}

题目大意:给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数。

思路:树状数组维护,从左到右扫一遍,第一次出现就在对应位置加1,第二次出现统计答案并把第一次出现的那个位置减1。

       CODE

#include<iostream>

#include<algorithm>

using namespace std;

 

intans=0,a[1000005],p[10000005],c[1000005],n;

int lb(int k)

{

return k & (-k);

}

void modify(int k,int d)

{

       while(k<=n*2)

       {

              c[k]+=d;

              k+=lb(k);

       }

}

int sum(int nn,int qq)

{

       while(nn>0)

       {

              qq+=c[nn];

              nn-=lb(nn);

       }

       returnqq;

}

int main()

{

   cin>>n;

       for(int i=1; i<=2*n; i++)

       {

              cin>>a[i];

              if(p[a[i]]==0) {

                     p[a[i]]=i;modify(i,1);

              }

              else{

                     ans=ans+sum(i,0)-sum(p[a[i]],0);

                     modify(p[a[i]],-1);

              }

       }

       cout<<ans;

   return 0;

}

0 0
原创粉丝点击