这道题一开始觉得是DP,感觉比较难优化就暂时没想
然后附近有人搜索过了,想了一下搜索感觉可以A*,但是一开始估值函数太保守了,时间卡不过去。
赛后问了一下过的人,是将这条路径之后的最大和平均加到已有的上面来比较
下附代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 ll dp[105][105],a[105][105],b[105][105],n,res=0,flag[105][105]; 5 ll tmp[205]; 6 ll f(ll x,ll y,ll suma,ll sumb) { 7 ll sum = dp[x][y]; 8 ll mov = min(sum, abs(suma - sumb)); 9 sum -= mov; 10 ll tmpval = sumb, tmpcnt = suma; 11 if (tmpval < tmpcnt) { 12 tmpval += mov; 13 } else { 14 tmpcnt += mov; 15 } 16 tmpcnt += (sum + 1) / 2; 17 tmpval += sum / 2; 18 return tmpcnt * tmpval; 19 } 20 struct node{ 21 ll x,y,suma,sumb; 22 bool operator < (node xx) const { 23 return f(x,y,suma,sumb)<f(xx.x,xx.y,xx.suma,xx.sumb); 24 } 25 }; 26 priority_queue<node> q; 27 int main(){ 28 int T; 29 scanf("%d",&T); 30 while (T--){ 31 res=0; 32 scanf("%lld",&n); 33 for (int i=1; i<=n; i++){ 34 for (int j=1; j<=n; j++){ 35 scanf("%lld",&a[i][j]); 36 } 37 } 38 for (int i=1; i<=n; i++){ 39 for (int j=1; j<=n; j++){ 40 scanf("%lld",&b[i][j]); 41 } 42 } 43 memset(dp,0,sizeof(dp)); 44 for (int i=n; i>=1; i--){ 45 for (int j=n; j>=1; j--){ 46 if (i==n && j==n) continue; 47 if (i==n) dp[i][j]=dp[i][j+1]+a[i][j+1]+b[i][j+1]; 48 else if (j==n) dp[i][j]=dp[i+1][j]+a[i+1][j]+b[i+1][j]; 49 else dp[i][j]=max(dp[i+1][j]+a[i+1][j]+b[i+1][j],dp[i][j+1]+a[i][j+1]+b[i][j+1]); 50 } 51 } 52 memset(flag,0,sizeof(flag)); 53 q.push({1,1,a[1][1],b[1][1]}); 54 while (!q.empty()){ 55 node x=q.top(); 56 q.pop(); 57 if (x.x==n && x.y==n){ 58 printf("%lld ",x.suma*x.sumb); 59 break; 60 } 61 if (x.x+1<=n) { 62 q.push({x.x+1,x.y,x.suma+a[x.x+1][x.y],x.sumb+b[x.x+1][x.y]}); 63 } 64 if (x.y+1<=n){ 65 q.push({x.x,x.y+1,x.suma+a[x.x][x.y+1],x.sumb+b[x.x][x.y+1]}); 66 } 67 } 68 while (!q.empty()){ 69 q.pop(); 70 } 71 } 72 }
PS:下次再不clear优先队列我就是狗