这题看了龙教主的报告才会做 Orz
http://acmicpc.org.cn/wiki/index.php?title=2009_Northwestern_Europe_Mountain_Road_Solution
/*
    题意:一条单向的公路  两端某些时刻有车过来
           给出这些车到达公路端的时间arrive,还有这些车通过这条公路的最短时间run
           要求相继通过某个点的两辆车时间不能少于10,也不能超车,而且不能打乱车来的顺序
           问怎么安排,使得最后通过公路的那辆车的时间最短

    题目给的限制具有顺序性,应想到dp

    dpA[i,j],dpB[i,j]分别表示两边刚好走了i,j辆车的最短时间,A刚走完,B刚走完
    转移的话枚举这某连续走K部车!!

    重要的是要理清车怎么跑:
    起始时间st = max(车到桥的时间T , 上一部车出发后+10)
    到达时间ed = max(车出发后全速前进 , 上一部车到达后+10)
    这样就保证了 “2车通过同一个点的时间间隔要至少是10秒” !!
    那么此时车行驶时间是ed-st

    启示:这里枚举连续走K部车,跟现实世界一样,放多少部车走    
*/
#include
<cstdio>
#include
<algorithm>

using namespace std;

const int MAXN = 210;
const int INF = 1000000000;

struct Car
{
    
int st,run;
};

int dpA[MAXN][MAXN],dpB[MAXN][MAXN];

Car carA[MAXN],carB[MAXN];

int main()
{
    
//freopen("in","r",stdin);
    int T;
    
for(scanf("%d",&T);T--;)
    {
        
int n,na=0,nb=0;
        
char ch;
        scanf(
"%d",&n);
        
for(int i=0;i<n;i++)
        {
            scanf(
" %c",&ch);
            
if(ch=='A')
            {
                na
++;
                scanf(
"%d%d",&carA[na].st,&carA[na].run);
            }
            
else
            {
                nb
++;
                scanf(
"%d%d",&carB[nb].st,&carB[nb].run);
            }
        }

        
//[i,j] -> [k,j]
        
//[i,j] -> [i,k]
        for(int i=0;i<=na;i++)
            
for(int j=0;j<=nb;j++)
                dpA[i][j]
=dpB[i][j]=INF;
        dpA[
0][0]=dpB[0][0]=0;
        
for(int i=0;i<=na;i++)
            
for(int j=0;j<=nb;j++)
            {
                
if(dpB[i][j]!=INF)
                {
                    
int st = max(carA[i+1].st,dpB[i][j]);
                    
int ed = st + carA[i+1].run;
                    dpA[i
+1][j] = min(dpA[i+1][j],ed);
                    
for(int k=i+2;k<=na;k++)
                    {
                        st 
= max(st+10,carA[k].st);//must more than st+10
                        ed = max(st+carA[k].run,ed+10);//must more than ed+10
                        dpA[k][j] = min(dpA[k][j],ed);                        
                    }
                }
                
if(dpA[i][j]!=INF)
                {
                    
int st = max(carB[j+1].st,dpA[i][j]);
                    
int ed = st + carB[j+1].run;
                    dpB[i][j
+1= min(dpB[i][j+1],ed);
                    
for(int k=j+2;k<=nb;k++)
                    {
                        st 
= max(st+10,carB[k].st);//must more than st+10
                        ed = max(st+carB[k].run,ed+10);//must more than ed+10
                        dpB[i][k] = min(dpB[i][k],ed);                        
                    }
                }
            }

        printf(
"%d\n",min(dpA[na][nb],dpB[na][nb]));
    }
    
return 0;
}