给出一个只包含 0 和 1 的 01 串 s ,下标从 1 开始,设第 i 位的价值为 vali ,则价值定义如下:
1. i=1时:val1 = 1
2. i>1时:
2.1 若 si ≠ si-1 , vali = 1
2.2 若 si = si-1 , vali = vali-1 + 1
字符串的价值等于 val1 + val2 + val3 + ... + valn
第一行一个正整数 n ,代表串长度。接下来一行一个 01 串 s 。1 ≤ n ≤ 5,000
输出一个整数代表答案
6 010101
7
删除后的串为0001或0111时有最大价值
20 11111000111011101100
94
4 1100
6
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); in.nextLine(); String s = in.nextLine(); int[] array = new int[n]; for (int i = 0; i < n; i++) { array[i] = s.charAt(i) - '0'; } int[][][] dp = new int[n][n + 1][2]; dp[0][1][array[0]] = 1; for (int i = 1; i < n; i++) { for (int j = 1; j <= n; j++) { if (j == 1) { for (int k = 0; k < n; k++) { if (array[i] == 0) { dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][k][1] + 1); dp[i][1][1] = dp[i - 1][1][1]; } else { dp[i][1][0] = dp[i - 1][1][0]; dp[i][1][1] = Math.max(dp[i][1][1], dp[i - 1][k][0] + 1); } } } else { if (array[i] == 0) { if (dp[i - 1][j - 1][0] != 0) { dp[i][j][0] = dp[i - 1][j - 1][0] + j; } dp[i][j][1] = dp[i - 1][j][1]; } else { dp[i][j][0] = dp[i - 1][j][0]; if (dp[i - 1][j - 1][1] != 0) { dp[i][j][1] = dp[i - 1][j - 1][1] + j; } } } } } int result = 0; for (int i = 0; i <= n; i++) { result = Math.max(result, dp[n - 1][i][0]); result = Math.max(result, dp[n - 1][i][1]); } System.out.println(result); } }
//贪心 public int valueOf01String(String str) { char[] s = str.toCharArray(); int n = s.length; int a = -1, b = -1; //记录第一个0和第一个1 int c = -1, d = -1; //记录最后一个0和最后一个1 int cnt0 = 0, cnt1 = 0;//记录0 和1的个数 for(int i = 0; i < n; i++) { if (a == -1 && s[i] == '0') a = i; if (b == -1 && s[i] == '1') b = i; if (s[i] == '0' && i > c) c = i; if (s[i] == '1' && i > d) d = i; if (s[i] == '0') cnt0++; else cnt1++; } return Math.max(C(cnt0) + C(a) + C(n - c - 1), C(cnt1) + C(b) + C(n - d - 1)); } int C(int n){return n * (n + 1) / 2;}