題意:已知有n個城市,某歌手每月進行一場演唱會,共持續c個月,可連續兩個月在同一個城市。城市間的路費已給出,且已知每個城市在第k(1<=k<=c)個月舉辦演唱會的所得利潤,求最終的最大利潤。
分析:第i個月在第j個城市舉辦演唱會,最終可得最大利潤,由此可得狀態轉移方程:dp[i][j] = max(dp[i][j], dp[i - 1][k] - d[k][j] + a[j].v[i])。
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<string>
5 #include<algorithm>
6 #include<cstdlib>
7 #include<cmath>
8 using namespace std;
9 const int MAXN = 100 + 10;
10 struct
11 {
12 int v[55];
13 }a[MAXN];
14 int d[MAXN][MAXN];
15 int dp[MAXN][MAXN];
16 int main()
17 {
18 int n;
19 scanf("%d", &n);
20 while(n--)
21 {
22 memset(d, 0, sizeof d);
23 memset(dp, 0, sizeof dp);
24 int s, c;
25 scanf("%d%d", &s, &c);
26 for(int i = 1; i <= s; ++i)
27 for(int j = 1; j <= c; ++j)
28 scanf("%d", &a[i].v[j]);
29 for(int i = 1; i <= s; ++i)
30 for(int j = 1; j <= s; ++j)
31 scanf("%d", &d[i][j]);
32 for(int i = 1; i <= s; ++i)
33 dp[1][i] = a[i].v[1];
34 for(int i = 2; i <= c; ++i)
35 for(int j = 1; j <= s; ++j)
36 for(int k = 1; k <= s; ++k)
37 dp[i][j] = max(dp[i][j], dp[i - 1][k] - d[k][j] + a[j].v[i]);
38 int ans = 0;
39 for(int i = 1; i <= s; ++i)
40 ans = max(ans, dp[c][i]);
41 printf("%d\n", ans);
42 }
43 return 0;
44 }