@@ -62,31 +62,53 @@ public static int ways1(int[] arr) {
6262// 如果i位置的数字变成了v,
6363// 并且arr[i]和arr[i+1]的关系为s,
6464// s==0,代表arr[i] < arr[i+1] 右大
65- // s==1,代表arr[i] == arr[i+1]
65+ // s==1,代表arr[i] == arr[i+1] 右=当前
6666// s==2,代表arr[i] > arr[i+1] 右小
6767// 返回0...i范围上有多少种有效的转化方式?
6868public static int process1 (int [] arr , int i , int v , int s ) {
6969if (i == 0 ) { // 0...i 只剩一个数了,0...0
70- return ((s == 0 || s == 1 ) && (arr [i ] == 0 || v == arr [i ])) ? 1 : 0 ;
70+ return ((s == 0 || s == 1 ) && (arr [0 ] == 0 || v == arr [0 ])) ? 1 : 0 ;
7171}
7272// i > 0
7373if (arr [i ] != 0 && v != arr [i ]) {
7474return 0 ;
7575}
76- // i>0 并且 i位置的数真的可以变成V,
76+ // i>0 ,并且, i位置的数真的可以变成V,
7777int ways = 0 ;
78- if (s == 0 || s == 1 ) { // [i - 1] [i] <= 右
78+ if (s == 0 || s == 1 ) { // [i] -> V <= [i+1]
7979for (int pre = 1 ; pre < 201 ; pre ++) {
8080ways += process1 (arr , i - 1 , pre , pre < v ? 0 : (pre == v ? 1 : 2 ));
8181}
82- } else { // s == 2 i > 右 i-1 >= i > 右
82+ } else { // ? 当前 > 右 当前 <= max{左,右}
8383for (int pre = v ; pre < 201 ; pre ++) {
8484ways += process1 (arr , i - 1 , pre , pre == v ? 1 : 2 );
8585}
8686}
8787return ways ;
8888}
8989
90+ public static int zuo (int [] arr , int i , int v , int s ) {
91+ if (i == 0 ) { // 0...i 只剩一个数了,0...0
92+ return ((s == 0 || s == 1 ) && (arr [0 ] == 0 || v == arr [0 ])) ? 1 : 0 ;
93+ }
94+ // i > 0
95+ if (arr [i ] != 0 && v != arr [i ]) {
96+ return 0 ;
97+ }
98+ // i>0 ,并且, i位置的数真的可以变成V,
99+ int ways = 0 ;
100+ if (s == 0 || s == 1 ) { // [i] -> V <= [i+1]
101+ for (int pre = 1 ; pre < v ; pre ++) {
102+ ways += zuo (arr , i - 1 , pre , 0 );
103+ }
104+ }
105+ ways += zuo (arr , i - 1 , v , 1 );
106+ for (int pre = v + 1 ; pre < 201 ; pre ++) {
107+ ways += zuo (arr , i - 1 , pre , 2 );
108+ }
109+ return ways ;
110+ }
111+
90112public static int ways2 (int [] arr ) {
91113int N = arr .length ;
92114int [][][] dp = new int [N ][201 ][3 ];
0 commit comments