[Topcoder SRM 499]【Solution】

55555,当时在学校没法捉……

250

有n只兔子,其中k(k<=n)只说了话,说话的形式如:和我一样颜色的有A[i]只!

然后问,满足这些话的情况下,n最小能是多少。

就是A[i]一样的贪心组合在一起即可。

550

给定一个数组A[i](i=0~n-1),假设你操作的序列是B[i](i=0~m-1)。

初始时m=1,B[0]=0

然后有3种操作:

1、将某个B[i] +1

2、将某个B[i] -1

3、选一个i然后

for (int j=m;j>i;j–) B[j]=B[j-1];

m++;

然后问最少进行多少操作,B[i]能和A[i]一样。

只要注意到复制以后,i和后面就可以断绝联系,这个区间dp的形式还是很明显的,F[i,j,k]表示区间[i,j]由一个初始时B[i]=k的复制而成至少需要多少次操作,然后枚举复制的位置和复制的长度就可以转移了。O(n^5) TC服务器无压力T_T

还有一种神贪心:

int getMinimum(vector

int ret=lines[0]+lines.size()-1;

for (int i=1;i

 if (lines[i]>lines[i-1]) ret+=lines[i]-lines[i-1];

return ret;

}

暂时只证明了他的充分性,必要性不会证T_T

 

1000

这个我觉得是我见过最简单的1000了啊啊啊T_T。

注意它可以交换相邻两个,那么你想想冒泡排序吧,于是所有的顺序都可以排出来了。所以用数量就可以描述一个点。

Tarjan缩环(注意缩完以后已经是拓扑序的了),然后dp求最长路就行了。每个点权就是k!/(pA! * pB! *pC! *pD!) pA表示’A’的数量……

 

TopCoder SRM 496

本次Rating降至空心黄

500搞了半天j打成i看不出来。。。交的时候都只剩200+分了。

最后500还是挂掉了,后来发现if里有个东西又打错了。。。一改Y了。

5555555555555555,现在神马都不行了。

在TC里那个字体太疼了= =。下次在外面打算了。

250

题目给定一个矩阵,每一笔你可以横向涂一笔连续的红的,或者竖向涂一笔连续的蓝的。如果一个格子被涂了红和蓝的,那么会变绿的。最后给出矩阵每个格子的颜色,问最少涂多少笔涂成这个样。

矩阵最大是50*50的。

……就是枚举。

class ColoredStrokes {
    vector    int m,n,ans;
    int v[55][55];
public:
    void solvex(){
      memset(v,0,sizeof(v));
      for (int i=0;i        for (int j=0;j          if ( (S[i][j]==’G’ || S[i][j]==’R’) && (!v[i][j]) ){
            for (int k=j;k              v[i][k]=1;
            ans++;
          }       
        }
    }
    
    void solvey(){
      memset(v,0,sizeof(v));
      for (int i=0;i        for (int j=0;j          if ( (S[i][j]==’B’ || S[i][j]==’G’) && (!v[i][j]) ){
            for (int k=i;k              v[k][j]=1;
            ans++;
          }
        }
    }
    
    int getLeast(vector       S=picture.begin();
      m=picture.size();
      n=picture[0].size();
      ans=0;
      solvex();
      solvey();
      return ans;
    }
};

 

500

有一些球在数轴上跑,然后他们都有一个相同的正的速度。(并且球不会发生碰撞)

然后他给出的第一个数组给定了一开始每个球的位置。

他又给了第二个数组,表示的是之后某个时刻每个球的位置。(但是有一些无关的球会被加进去)

假设way[i]表示第一个数组中第i个球是第二个数组中第way[i]个球,那么问way这个数组有多少种可能的不同的取值。

两个数组中的元素个数都<=50,题目保证了两个数组中,都不会有重复的数值。

样例:


具体做法就是先枚举他们的速度,设为dis。(显然速度只能是 abs(a[i]-b[j]) )

接下来我们来建边:

a[i] ->  (a[i]-dis) in b[j]

a[i] ->  (a[i]+dis) in b[j]

对于a[i],如果不存在其它的a[j]和它争b数组中的结点,那么显然他连出去多少条边,就有多少种方案,然后利用乘法原理乘起来就行。

然后我们关注发生冲突的。因为a,b数组中都不包含重复元素,那么发生冲突只能是这样情况:

a[i]+dis=a[j]-dis

然后继续发生冲突:a[j]+dis=a[k]-dis…

如此下去就会变成一条链。

然后……就判一个每个结点-dis和+dis的是否在b数组中存在。然后匹配时对于这条链,要么全-dis,要么全+dis,要么从中间部分开始,前一半-dis,后一半+dis……于是就这样每条链分开讨论,乘法原理将方案数乘起来。

然后再根据加法原理把不同速度的方案加起来。得到解。

class OneDimensionalBalls {
public:
    int up[55];
    int down[55];
    int m,n;
    int a[55];
    int b[55];
    int v[55];
    int tail;
    int dis;
    int List[55*55];
    
    void make_up_down(){
      int i,j;
      memset(up,0,sizeof(up));
      memset(down,0,sizeof(down));
      for (i=0;i        for (j=0;j          if (a[i]-dis==b[j]) up[i]=1;
          if (a[i]+dis==b[j]) down[i]=1;
        }
    }
    
    int Q[55];
    int Qt;
    int Link(int st){
      int i;
      Qt=1; Q[1]=st;
      v[st]=1;
      for (i=st+1;i        if (a[i]-a[Q[Qt]]==2*dis && down[Q[Qt]]){
          v[i]=1;
          Q[++Qt]=i;
        }
      int ed=Q[Qt];
      if (!up[st] && !down[ed]) return 0;
      if (!up[st]) return 1;
      if (!down[ed]) return 1;
      return Qt+1;
    }
    
    long long countValidGuesses(vector       m=firstPicture.size();
      n=secondPicture.size();
      for (int i=0;i      for (int i=0;i      sort(a,a+m);
      sort(b,b+n);
      tail=0;
      for (int i=0;i        for (int j=0;j          if (a[i]!=b[j])
            List[++tail]=abs(a[i]-b[j]);
      long long ans=0;
      long long now;
      sort(List+1,List+tail+1);
      for (int i=1;i<=tail;i++)
        if (i==1 || List[i]!=List[i-1]){
          dis=List[i];
          make_up_down();
          memset(v,0,sizeof(v));
          now=1;
          for (int j=0;j            if (!v[j])
              now*=Link(j);
          ans+=now;
        }
      return ans;
    }
};

 

950

推荐hhanger大神的解题报告

TopCoder 【Practice Room】 之处女交

觉得也是时候玩玩TopCoder了。。。然后之前注册edward_mj的号怎么登都登不了= =,即使用邮箱改了密码,还是显示我账号密码不对。于是就换了一个号。接下来按照这篇东西介绍的进到去以后,选了SRM494 DIV 2 250分那题。。。

然后进去一看。我晕,怎么要用vector

然后看到首当其冲的:vector未定义。。。我倒,vector未定义,那你还传给我干嘛= =。然后加了一堆头文件以后,终于过了。

看来头文件都要先搞好,怪不得以前听别人说TC的模板什么的一大串,原来就是这种东西。。。

中间切出去各种看百度神马的,又看到右上角“CODING 00:00:00”还以为他不算时间

然后DIV2 250的Trash题就变成这样了。。。

System> cwj has submitted the 250-point problem for 146.60 points