题目链接在这里:Problem - A - Codeforces
第一眼以为是大讨论,但是自己想感觉根本无从下手,于是考虑了这种动态规划的方法,注意,此题如果按照当前状态由哪些前驱状态推得来动归的话会极其麻烦,因为并不能确定上一个状态是什么样子。所以考虑由当前状态去推到后继状态。
很显然这里有两种情况,一种是直接到25就胜,一种是必须比另一个高两分才胜。根据这两种情况枚举状态就行。
这道题需要学习的一个是这种状态定义的方法,每一维表示一种状态;状态转移的过程需要写成由当前状态推到后继状态,这在状态转移的途径很多且不确定的时候需要用这种写法;通过vector容器记录路径的方法,并且要注意在路径合并的过程中由于答案不唯一,所以每个节点只能被访问一次,否则路径会记混。
1 #include "bits/stdc++.h" 2 using namespace std; 3 const int MAX=205; 4 int t,a,b,f[5][5][MAX][MAX]; 5 vector <pair<int,int> > vec[5][5][MAX][MAX]; 6 int main(){ 7 freopen ("a.in","r",stdin); 8 freopen ("a.out","w",stdout); 9 int i,j,c,v,k,win; 10 scanf("%d",&t); 11 memset(f,0,sizeof(f)); 12 f[0][0][0][0]=1; 13 for (i=0;i<=2;i++) 14 for (j=0;j<=2;j++) 15 for (c=0;c<MAX;c++) 16 for (v=0;v<MAX;v++){ 17 if (i==2 && j==2) win=15; 18 else win=25; 19 for (k=win-1;k<MAX;k++){ 20 if (f[i][j][c][v] && !f[i+1][j][c+k+2][v+k] && c+k+2<MAX && v+k<MAX){ 21 f[i+1][j][c+k+2][v+k]=f[i][j][c][v]; 22 vec[i+1][j][c+k+2][v+k]=vec[i][j][c][v]; 23 vec[i+1][j][c+k+2][v+k].push_back(make_pair(k+2,k)); 24 } 25 if (f[i][j][c][v] && !f[i][j+1][c+k][v+k+2] && c+k<MAX && v+k+2<MAX){ 26 f[i][j+1][c+k][v+k+2]=f[i][j][c][v]; 27 vec[i][j+1][c+k][v+k+2]=vec[i][j][c][v]; 28 vec[i][j+1][c+k][v+k+2].push_back(make_pair(k,k+2)); 29 } 30 } 31 for (k=0;k<=win-2;k++){ 32 if (f[i][j][c][v] && !f[i+1][j][c+win][v+k] && c+win<MAX && v+k<MAX){ 33 f[i+1][j][c+win][v+k]=f[i][j][c][v]; 34 vec[i+1][j][c+win][v+k]=vec[i][j][c][v]; 35 vec[i+1][j][c+win][v+k].push_back(make_pair(win,k)); 36 } 37 if (f[i][j][c][v] && !f[i][j+1][c+k][v+win] && c+k<MAX && v+win<MAX){ 38 f[i][j+1][c+k][v+win]=f[i][j][c][v]; 39 vec[i][j+1][c+k][v+win]=vec[i][j][c][v]; 40 vec[i][j+1][c+k][v+win].push_back(make_pair(k,win)); 41 } 42 } 43 } 44 while (t--){ 45 scanf("%d%d",&a,&b); 46 if (f[3][0][a][b]){ 47 printf("3:0\n"); 48 for (i=0;i<vec[3][0][a][b].size();i++) 49 printf("%d:%d ",vec[3][0][a][b][i].first,vec[3][0][a][b][i].second); 50 printf("\n"); 51 } 52 else if (f[3][1][a][b]){ 53 printf("3:1\n"); 54 for (i=0;i<vec[3][1][a][b].size();i++) 55 printf("%d:%d ",vec[3][1][a][b][i].first,vec[3][1][a][b][i].second); 56 printf("\n"); 57 } 58 else if (f[3][2][a][b]){ 59 printf("3:2\n"); 60 for (i=0;i<vec[3][2][a][b].size();i++) 61 printf("%d:%d ",vec[3][2][a][b][i].first,vec[3][2][a][b][i].second); 62 printf("\n"); 63 } 64 else if (f[2][3][a][b]){ 65 printf("2:3\n"); 66 for (i=0;i<vec[2][3][a][b].size();i++) 67 printf("%d:%d ",vec[2][3][a][b][i].first,vec[2][3][a][b][i].second); 68 printf("\n"); 69 } 70 else if (f[1][3][a][b]){ 71 printf("1:3\n"); 72 for (i=0;i<vec[1][3][a][b].size();i++) 73 printf("%d:%d ",vec[1][3][a][b][i].first,vec[1][3][a][b][i].second); 74 printf("\n"); 75 } 76 else if (f[0][3][a][b]){ 77 printf("0:3\n"); 78 for (i=0;i<vec[0][3][a][b].size();i++) 79 printf("%d:%d ",vec[0][3][a][b][i].first,vec[0][3][a][b][i].second); 80 printf("\n"); 81 } 82 else printf("Impossible\n"); 83 } 84 return 0; 85 }
未来是什么样,未来会发生什么,谁也不知道。
但是我知道,
起码从今天开始努力,
肯定比从明天开始努力,
要快一天实现梦想。
千里之行,始于足下! ——《那年那兔那些事儿》