1.
Vínculo con el
problema de la fusión de piedras. Solución: Para fusionar un intervalo de longitud 2, suponiendo que el intervalo es un montón de arena como punto de partida, usamos dp [a] [a + 1] para representar su valor, luego dp [a] [a + 1] = dp [a] [a] + dp [a + 1] dp [a] [a + 1] = dp [a] [a] + dp [a + 1]d p [ a ] [ a+1 ]=d p [ a ] [ a ]+d p [ a+1 ] [a + 1] + valor [a] + valor [a + 1]. 对于 一个 区间 长度 为 3 的,dp [a] [a + 2] = min (dp [a] [a] + dp [ a + 1] [a + 2], dp [a] [a + 1] + dp [a + 2] [a + 2]) + valor [a] + valor [a + 1] + valor [a + 3 ] dp [a] [a + 2] = min (dp [a] [a] + dp [a + 1] [a + 2], dp [a] [a + 1] + dp [a + 2] [ a + 2]) + valor [a] + valor [a + 1] + valor [a + 3]d p [ a ] [ a+2 ]=m i n ( d p [ a ] [ a ]+d p [ a+1 ] [ a+2 ] ,d p [ a ] [ a+1 ]+d p [ a+2 ] [ a+2 ] )+v a l u e [ a ]+v a l u e [ a+1 ]+v a l u e [ a+3 ]
Para la siguiente adición, podemos usar prefijo y para preprocesamiento
Código:
#include <iostream>
#include <math.h>
using namespace std;
const int N = 310;
int a[310];
int dp[N][N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
dp[i][i] = 0;
}
for (int i = 1; i <= n; i++)
a[i] += a[i - 1];
for (int l = 2; l <= n; l++)
for (int b = 1; b <= n - l + 1; b++)
{
int tail = b + l - 1;
if (b != tail)
dp[b][tail] = 9999999;
for (int k = b; k < tail; k++)
dp[b][tail] = min(dp[b][tail], dp[b][k] + dp[k + 1][tail] + a[tail] - a[b - 1]);
}
cout << dp[1][n] << endl;
}
Enlace del
tema del polígono
Solución del problema: para un anillo, generalmente nos gusta romperlo una vez
, asumiendo que rompemos 1 y n, luego encontramos el valor máximo de 1 ~ n para fusionar, asumiendo que el corto es 1 y 2., Luego encontramos el valor máximo de 2 ~ n + 1 para fusionar. Debido a que no estamos seguros de estar desconectados de allí, tenemos que considerar cada caso. Luego esta pregunta se transforma en una pregunta similar a la primera pregunta, excepto La forma de fusionar es diferente.
Código:
#include <iostream>
#include <queue>
#include <math.h>
#include <string.h>
using namespace std;
const int N = 51;
int dian[2 * N];
char bian[2 * N];
int maxs[3 * N][3 * N], mins[3 * N][3 * N];
int suan(int a, char b, int c)
{
if (b == 't')
{
return a + c;
}
else
{
return a * c;
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> bian[i] >> dian[i];
bian[n + i] = bian[i];
dian[n + i] = dian[i];
}
int most = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= 2 * n - i + 1; j++)
{
if (i == 1)
{
maxs[j][j] = dian[j];
mins[j][j] = dian[j];
maxs[n + j][n + j] = dian[j];
mins[n + j][n + j] = dian[j];
}
else
{
maxs[j][j + i - 1] = -32767;
mins[j][j + i - 1] = 32767;
for (int k = j + 1; k - j + 1 <= i; k++)
{
int z = suan(maxs[j][k - 1], bian[k], maxs[k][j + i - 1]);
int x = suan(mins[j][k - 1], bian[k], mins[k][j + i - 1]);
int c = suan(mins[j][k - 1], bian[k], maxs[k][j + i - 1]);
int v = suan(maxs[j][k - 1], bian[k], mins[k][j + i - 1]);
maxs[j][j + i - 1] = max(maxs[j][j + i - 1], max(z, max(x, max(c, v))));
mins[j][j + i - 1] = min(mins[j][j + i - 1], min(z, min(x, min(c, v))));
if (i == n)
{
most = max(most, maxs[j][j + n - 1]);
}
}
}
}
cout << most << endl;
for (int i = 1; i <= n; i++)
{
if (maxs[i][i + n - 1] == most)
cout << i << " ";
}
}
3. Pirámide
de vínculo a temas
Solución:
(préstamo Autor: no les importa un poco de tabla del número de ac)
Código:
#include<iostream>
#include<math.h>
#include<string>
#include<string.h>
using namespace std;
typedef long long ll;
const int mod=1e9;
const int N=310;
ll dp[N][N];
int main()
{
string a;
cin>>a;
int n=a.length();
for(int i=1;i<=a.length();i+=2)
for(int l=0;l<=n-i+1;l++)
{
int tail=l+i-1;
if(i==1)dp[l][l]=1;
else if(a[l]==a[tail])
{
for(int k=l;k<tail;k=k+2)
{
if(a[k]==a[tail])
dp[l][tail]=(dp[l][tail]+dp[l][k]*dp[k+1][tail-1])%mod;
}
}
}
cout<<dp[0][a.length()-1]<<endl;
}