JZOJ7月5日提高组T2 分手是祝愿
题目
Description
Input
Output
Sample Input
2
2
15 19
3
30 40 20
Sample Output
285
2600
Data Constraint
题解
分析
- 设 F [ i ] [ j ] F[i][j] F[i][j]表示 i i i~ j j j这个区间所需要的最小体力值
- 设 G [ i ] [ j ] G[i][j] G[i][j]表示 i i i~ j j j这个区间最终合成的礼物的魔法值
那么对于
i
i
i~
j
j
j这个区间
可以由
i
i
i~
k
k
k和
k
+
1
k+1
k+1 ~
j
j
j
(
i
≤
k
≤
j
)
(i≤k≤j)
(i≤k≤j)两个区间合并得到
有转移方程
f
[
i
]
[
j
]
=
f
[
i
]
[
k
]
+
f
[
k
+
1
]
[
j
]
+
g
[
i
]
[
k
]
∗
g
[
k
+
1
]
[
j
]
(
前
提
是
f
[
i
]
[
j
]
>
f
[
i
]
[
k
]
+
f
[
k
+
1
]
[
j
]
+
g
[
i
]
[
k
]
∗
g
[
k
+
1
]
[
j
]
)
f[i][j]=f[i][k]+f[k+1][j]+g[i][k]*g[k+1][j](前提是f[i][j]>f[i][k]+f[k+1][j]+g[i][k]*g[k+1][j])
f[i][j]=f[i][k]+f[k+1][j]+g[i][k]∗g[k+1][j](前提是f[i][j]>f[i][k]+f[k+1][j]+g[i][k]∗g[k+1][j])
更新
g
[
i
]
[
j
]
g[i][j]
g[i][j]:
g
[
i
]
[
j
]
=
g
[
i
]
[
k
]
∗
g
[
k
+
1
]
[
j
]
g[i][j]=g[i][k]*g[k+1][j]
g[i][j]=g[i][k]∗g[k+1][j]
别忘了模数
Code
#include<cstdio>
#include<cstring>
using namespace std;
int t,n,i;
int f[105][105],a[105][105];
int dfs(int l,int r)
{
int i,x,y;
if (f[l][r]>=0) return f[l][r];
for (i=l;i<r;i++)
{
x=dfs(l,i);
y=dfs(i+1,r);
if (f[l][r]<0||x+y+a[l][i]*a[i+1][r]<f[l][r])
{
f[l][r]=x+y+a[l][i]*a[i+1][r];
a[l][r]=(a[l][i]+a[i+1][r])%100;
}
}
return f[l][r];
}
int main()
{
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
memset(f,-1,sizeof(f));
memset(a,-1,sizeof(a));
for (i=1;i<=n;i++)
{
f[i][i]=0;
scanf("%d",&a[i][i]);
}
printf("%d\n",dfs(1,n));
}
return 0;
}