变色DNA(最短路思维题)

个人心得:太水了,还是对最短路不太深入了解,无法构建出最短路模板,然后就是读题能力,

这题的关键在于转换为最短路模板,因为DFS我在24组超时了。

假设把从i到j的代价看做是权值,那么就是对权值的确立了,显而易见,权值跟前面出现的Y的个数有关。

权值建立后就可以用最短路了,特意看了下最短路深入了解了下,每次选择最短的确实可以确定此时的到x的最短路径。

一个话:多思考,多思考

题目:

有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1,2...N-1。研究发现这只狼的基因中存在一个变色矩阵,记为colormap,如果colormapiijj='Y'则这只狼可以在某一个夜晚从颜色i变成颜色j(一晚不可以变色多次),如果colormapiijj=‘N’则不能在一个晚上从i变成j色。进一步研究发现,这只狼每次变色并不是随机变的,它有一定策略,在每个夜晚,如果它没法改变它的颜色,那么它就不变色,如果存在可改变的颜色,那它变为标号尽可能小的颜色(可以变色时它一定变色,哪怕变完后颜色标号比现在的大)。现在这只狼是颜色0,你想让其变为颜色N-1,你有一项技术可以改变狼的一些基因,具体说你可以花费1的代价,将狼的变色矩阵中的某一个colormapiijj='Y'改变成colormapiijj='N'。问至少花费多少总代价改变狼的基因,让狼按它的变色策略可以从颜色0经过若干天的变色变成颜色N-1。如果一定不能变成N-1,则输出-1. 
Input多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5 
每组测试数据有相同的结构构成: 
每组数据第一行一个整数N,2<=N<=50。 
之后有N行,每行N个字符,表示狼的变色矩阵,矩阵中只有‘Y’与‘N’两种字符,第i行第j列的字符就是colormapiijj。Output每组数据一行输出,即最小代价,无解时输出-1。Sample Input

3
3
NYN
YNY
NNN
8
NNNNNNNY
NNNNYYYY
YNNNNYYN
NNNNNYYY
YYYNNNNN
YNYNYNYN
NYNYNYNY
YYYYYYYN
6
NYYYYN
YNYYYN
YYNYYN
YYYNYN
YYYYNN
YYYYYN

Sample Output

1
0
-1
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<vector>
 6 #include<queue>
 7 #include<string>
 8 #include<algorithm>
 9 using namespace std;
10 const int inf=0x3f3f3f3f;
11 char mymap[55][55];
12 int book[55];
13 int s[55][55];
14 int cost[55];
15 int d[55];
16 struct node
17 {
18     int number,dis;
19     node(int a,int b)
20     {
21         number=a,dis=b;
22     }
23 };
24 int sum=inf;
25 int t,n;
26 vector<int >v[55];
27 bool operator<(const node& a,const node& b)
28 {
29     return a.dis<b.dis;
30 }
31 int solve(){
32     for(int i=0;i<n;i++)
33         d[i]=inf;
34     memset(book,0,sizeof(book));
35     priority_queue<node >q;
36     q.push(node(0,0));
37     d[0]=0;
38     while(!q.empty()){
39         node p=q.top();
40         q.pop();
41         int x=p.number;
42         for(int i=0;i<v[x].size();i++)
43         {
44             int u=v[x][i];
45             if(d[u]>d[x]+s[x][u])
46             {
47                 d[u]=d[x]+s[x][u];
48                 q.push(node(u,d[u]));
49             }
50         }
51     }
52     return d[n-1]==inf?-1:d[n-1];
53 }
54 int main(){
55     scanf("%d",&t);
56     while(t--){
57         scanf("%d",&n);
58         memset(s,0,sizeof(s));
59         for(int i=0;i<n;i++)
60             for(int j=0;j<n;j++)
61                 s[i][j]=(i==j)?0:inf;
62         for(int i=0;i<n;i++)
63            {
64                scanf("%s",mymap[i]);
65                int nu=0;
66                for(int j=0;j<n;j++)
67                {
68               if(mymap[i][j]=='Y'){
69                 v[i].push_back(j);
70               cost[j]=(j==0)?1:cost[j-1]+1;
71               }
72               else
73                 cost[j]=(j==0)?0:cost[j-1];
74                 s[i][j]=(j==0)?0:cost[j-1];
75                }
76            }
77            cout<<solve()<<endl;
78            for(int i=0;i<n;i++)
79             v[i].clear();
80     }
81 
82 
83     return 0;
84 }

 



posted @ 2017-12-09 18:50  余生漫漫浪  阅读(454)  评论(0编辑  收藏  举报