USACO 5.4 Twofive(DP)
非常不容易的一题,思路就是DP之后输出路径。但是此题,路径和DP的方式不一样,路径要按字典序输出。
开始写了一个版本,N 10000的时候就是过不了,后来才发现,自己的写法有问题,无法保证字典序。看了看题解,其实也不是很懂。
终于还有3个题,加油了!!
1 /* 2 ID: cuizhe 3 LANG: C++ 4 TASK: twofive 5 */ 6 #include <cstdio> 7 #include <cstring> 8 using namespace std; 9 char str[101]; 10 char te[101]; 11 int dp[6][6][6][6][6]; 12 int judge(int x,int step) 13 { 14 if(!te[x]||te[x] == step + 'A') 15 return 1; 16 else 17 return 0; 18 } 19 int dfs(int x1,int x2,int x3,int x4,int x5,int step) 20 { 21 int ans = 0; 22 if(step == 25) 23 return 1; 24 if(dp[x1][x2][x3][x4][x5]) 25 return dp[x1][x2][x3][x4][x5]; 26 if(x1 < 5&&judge(x1,step)) 27 ans += dfs(x1+1,x2,x3,x4,x5,step+1); 28 if(x2 < x1&&judge(x2+5,step)) 29 ans += dfs(x1,x2+1,x3,x4,x5,step+1); 30 if(x3 < x2&&judge(x3+10,step)) 31 ans += dfs(x1,x2,x3+1,x4,x5,step+1); 32 if(x4 < x3&&judge(x4+15,step)) 33 ans += dfs(x1,x2,x3,x4+1,x5,step+1); 34 if(x5 < x4&&judge(x5+20,step)) 35 ans += dfs(x1,x2,x3,x4,x5+1,step+1); 36 return dp[x1][x2][x3][x4][x5] = ans; 37 } 38 int main() 39 { 40 char ch[10]; 41 freopen("twofive.in","r",stdin); 42 freopen("twofive.out","w",stdout); 43 int n,i,temp,ans; 44 scanf("%s",ch); 45 if(ch[0] == 'N') 46 { 47 scanf("%d",&n); 48 for(i = 0;i < 25;i ++) 49 { 50 for(te[i] = 'A';;te[i] ++) 51 { 52 memset(dp,0,sizeof(dp)); 53 if((temp = dfs(0,0,0,0,0,0)) < n) 54 n -= temp; 55 else 56 break; 57 } 58 } 59 te[25] = '\0'; 60 printf("%s\n",te); 61 } 62 else 63 { 64 scanf("%s",str); 65 for(i = 0;i < 25;i ++) 66 { 67 for(te[i] = 'A';te[i] < str[i];te[i] ++) 68 { 69 memset(dp,0,sizeof(dp)); 70 ans += dfs(0,0,0,0,0,0); 71 } 72 } 73 printf("%d\n",ans+1); 74 } 75 return 0; 76 }