1. 程式人生 > 實用技巧 >Edu Round#93(div2)

Edu Round#93(div2)

有多菜就不用說了,我是真的不會做,真的不是教育場坑的原因。

C. Good Subarrays

給一個數組 \(A\) , $A_i \in [0,9] $ , 求區間和等於區間長度的區間個數

想到了是不是尺取,但是如果全一的資料顯然不能。

又想到了 \(dp\)

想到了,我真菜

$A_i = A_i - 1 $ , 則轉化為區間和為 \(0\) , 就變成了之前有多少個字首和與目前相等

... 我好菜

scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        int x,sum = 0;
        long long ans = 0;
        map<int,int>P;P[0]++;
        for(int i = 1;i <= n;i++){
            scanf("%1d",&x);
            sum += x-1;
            ans += P[sum];
            P[sum]++;
        }
        printf("%lld\n",ans);    
    }

D. Colored Rectangles

有若干對三種顏色的木棍,給出他們的長度,選取不同顏色的兩對木棍行成矩形,求最大的面積之和。

最先開始想的是直接貪心,但是碰到如下資料就不能貪心

7 8

9

10

如果貪心搞 9 和 10 的話,就浪費了第一種顏色的兩對

後來又搞了dfs暴力,穩妥妥的 t 了。

然後搞了個記憶化,結果腦子有點迷糊。

好像是一個三維dp...

我吐了,跟昨天寫的記憶化搜尋差不多,稍微改一下就過了

/* Author: coding_like_cxk
 * Time: 2020-08-15 10:35:01
**/

#include<bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;

int a, b, c;
int A[220], B[220], C[220];
int dp[220][220][220];

int ans;

int dfs(int x, int y, int z) {
	int cnt = 0;
	if (dp[x][y][z] != 0)return dp[x][y][z];

	if (x > 0)cnt++; if (y > 0)cnt++; if (z > 0)cnt++;
	if (cnt < 2) {
		return dp[x][y][z] = 0;
	}
	int ans = 0;

	if (x > 0 && y > 0) {
		ans = max(ans, dfs(x - 1, y - 1, z) + A[x] * B[y]);
	}
	if (x > 0 && z > 0) {
		ans = max(ans, dfs(x - 1, y, z - 1) + A[x] * C[z]);
	}
	if (y > 0 && z > 0) {
		ans = max(ans, dfs(x, y - 1, z - 1) + B[y] * C[z]);
	}
	return dp[x][y][z] = ans;
}
int main() {
	cin >> a >> b >> c;
	for (int i = 1; i <= a; i++)cin >> A[i];
	for (int i = 1; i <= b; i++)cin >> B[i];
	for (int i = 1; i <= c; i++)cin >> C[i];
	sort(A + 1, A + a + 1); sort(B + 1, B + b + 1); sort(C + 1, C + c + 1);

	cout << dfs(a, b, c) << endl;
}