题目链接:https://ac.nowcoder.com/acm/contest/886/J
题目大意:
有n个种类的树,每个种类对应m个级别。每个种类升级都需要一定的成本,且当n个种类的等级都达到一个等级时,将获得这个等级的利润,问能获得的最大金额。
解题报告:
学到了新的东西:最小子串和,可以记录从i点开始往后的最小自串和。
题解都在代码里,根据当前的矩阵前缀和,和找n-1条子串的最小子串和(因为是成本所以要最小,至多n-1条边,否则就构成矩阵了,没必要重复判断)。
AC代码:
1 #include<bits/stdc++.h> 2 #define numm ch-48 3 #define pd putchar(' ') 4 #define pn putchar('\n') 5 #define pb push_back 6 #define fi first 7 #define se second 8 #define fre1 freopen("1.txt","r",stdin) 9 #define fre2 freopen("2.txt","w",stdout) 10 using namespace std; 11 template <typename T> 12 void read(T &res) { 13 bool flag=false;char ch; 14 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 15 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 16 flag&&(res=-res); 17 } 18 template <typename T> 19 void write(T x) { 20 if(x<0) putchar('-'),x=-x; 21 if(x>9) write(x/10); 22 putchar(x%10+'0'); 23 } 24 25 typedef long long ll; 26 const int maxn=1010; 27 const int N=60; 28 const int inf=0x3f3f3f3f; 29 const ll INF=0x3f3f3f3f3f3f3f3f; 30 const int mod=998244353; 31 32 ll mp[maxn][maxn]; ///每行每列的元素 33 ll d[maxn]; ///每列的利润 34 ll wtz[maxn]; ///记录从1到i列的矩阵前缀和 35 ll dp[maxn][maxn]; ///记录最小子串和 36 ll ls[maxn]; ///利润前缀和 37 int main() 38 { 39 int _,k=0,n,m; 40 read(_); 41 while(_--) { 42 read(n),read(m); 43 for(int i=1;i<=n;i++) 44 wtz[i]=0; 45 for(int i=1;i<=n;i++) 46 for(int j=1;j<=m;j++) { 47 read(mp[i][j]); 48 wtz[j]+=mp[i][j]; 49 } 50 for(int i=1;i<=m;i++) ///从1到i列的矩阵前缀和 51 wtz[i]+=wtz[i-1]; 52 for(int i=1;i<=n;i++) { ///记录最小子串和 53 dp[i][m+1]=0; 54 for(int j=m;j>=1;j--) 55 dp[i][j]=min(dp[i][j+1]+mp[i][j],mp[i][j]); 56 } 57 for(int i=1;i<=n;i++) 58 for(int j=1;j<=m;j++) 59 if(dp[i][j]>0) 60 dp[i][j]=0; 61 for(int i=1;i<=m;i++) { 62 read(d[i]); 63 ls[i]=ls[i-1]+d[i]; 64 } 65 ll res=0; 66 for(int i=1;i<=m;i++) { 67 ll sum=0,del=-INF; 68 for(int j=1;j<=n;j++) { 69 del=max(dp[j][i],del); ///要减掉的那一行 70 sum+=dp[j][i]; 71 } 72 res=max(ls[i-1]-(sum-del)-wtz[i-1],res); ///利润-子串和(至多n-1个)+矩阵前缀和 73 } 74 res=max(ls[m]-wtz[m],res); 75 printf("Case #%d: ",++k); 76 write(res);pn; 77 } 78 return 0; 79 }