题目描述
阿冷喜欢种树,但他有个奇怪的爱好,他喜欢将连续相同种类的树当成一片森林。
(比如trees=[0,1,1,2,2,2,1],它包含4片森林,[{0}, {1,1}, {2,2,2}, {1}])
现在有m颗树,有n种树的种类(数的种类从1到n)
并给出在位置i,种植种类为j的树所消耗的力气 cost[i][j]
求阿冷最终将m颗树种植成k片森林的最少消耗的力气。
输入
第一行有一个参数T, 代表有T组样例
接下来一行 有三个参数 m, n, k 代表 m颗树, n种树,以及最终需要的森林数
接下来有m行,每行有n个参数,分别代表在位置i, 种植种类为j的树所消耗的力气。
1 <= T <= 5
1 <= m <= 100
1 <= n <= 10
1 <= k <= m
1 <= cost[i][j] <= 50
输出
对于每一个样例,每行输出最少消耗的力气,不存在的情况输出-1
样例输入
1 2 2 1 2 5 1 3
样例输出
3
提示
2颗树 2种树 最后需要生成一片森林
第一颗树 种植为种类1 所需要的力气为 2
第一颗树 种植为种类2 所需要的力气为 5
第二颗树 种植为种类1 所需要的力气为 1
第二颗树 种植为种类2 所需要的力气为 3
因而形成一片森林 所需要的最少力气为3 (即将第一棵树和第二颗都种植种类为1的树)
题型: 动态规划
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
const int M = 15;
int dp[N][M][N]; // dp[i][j][k] ±Ì æ µΩµ⁄iø≈ ˜, ≤¢«“µ⁄iø≈ ˜ π”√µ⁄j÷÷£¨◊Ó∫Û–Œ≥…k∆¨…≠¡÷µƒ◊Ó–°¡¶∆¯
int m, n, k;
int cost[N][N];
const int INF = 0x3f3f3f3f;
int main()
{
// freopen("../../in.txt", "r", stdin);
int T;
cin >> T;
while (T--)
{
scanf("%d %d %d", &m, &n, &k);// m颗树, n种树,以及最终需要的森林数
for (int i=1; i<=m; i++)
{
for (int j=1; j<=n; j++)
{
scanf("%d", &cost[i][j]);
}
}//输入代价
memset(dp, 0x3f, sizeof(dp));
// µ⁄“ªø≈ ˜£¨÷÷¿‡Œ™i, 1∆¨…≠¡÷µƒ¥˙º€ « cost[1][i]
for (int i=1; i<=n; i++)
{
dp[1][i][1] = cost[1][i];
}
for (int i=2; i<=m; i++)//m棵树
{
for (int pre=1; pre<=n; pre++)//位置
{
for (int now=1; now<=n; now++)//位置
{
for (int tt=0; tt<=k; tt++)//树种
{
if (pre == now)//位置pre和now选择的是同一种树,不会增加森林
{
dp[i][now][tt] = min(dp[i][now][tt], dp[i-1][pre][tt] + cost[i][now]);
}
else
{
if (tt > 0)
dp[i][now][tt] = min(dp[i][now][tt], dp[i-1][pre][tt-1] + cost[i][now]);
}
}
}
}
}
int res = INF;
for (int i=1; i<=n; i++)
{
res = min(res, dp[m][i][k]);
}
res = (res >= INF) ? -1 : res;
cout << res << endl;
}
return 0;
}