思路:即求给定的数组删除几次变成0,那么从min(n,m)方向开始删除即有最优解,两个方向都跑一遍就行。
# include <bits/stdc++.h>
using namespace std;
int a[103][103], l[103], b[103][103], r[103];
int main()
{
int n, m, sum = 0, ans = 0, ans2 = 0;
scanf("%d%d",&n,&m);
memset(l, 0x3f, sizeof(l));
memset(r, 0x3f, sizeof(r));
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; ++j)
{
scanf("%d",&a[i][j]);
b[j][i] = a[i][j];
sum += a[i][j];
r[j] = min(r[j], b[j][i]);
l[i] = min(l[i], a[i][j]);
}
}
for(int i=1; i<=n; ++i)
{
sum -= l[i]*m;
ans += l[i];
for(int j=1; j<=m; ++j)
{
a[i][j] -= l[i];
}
}
for(int i=1; i<=m; ++i)
{
ans2 += r[i];
for(int j=1; j<=n; ++j)
{
b[i][j] -= r[i];
}
}
for(int i=1; i<=m; ++i)
{
if(a[1][i] != 0)
{
for(int j=2; j<=n; ++j)
if(a[j][i] != a[j-1][i])
return 0*puts("-1");
ans += a[1][i];
sum -= a[1][i]*n;
}
}
for(int i=1; i<=n; ++i)
if(b[1][i] != 0)
ans2 += b[1][i];
if(sum) return 0*puts("-1");
if(ans <= ans2)
{
printf("%d\n",ans);
for(int i=1; i<=n; ++i)
for(int j=1; j<=l[i]; ++j)
printf("row %d\n",i);
for(int i=1; i<=m; ++i)
for(int j=1; j<=a[1][i]; ++j)
printf("col %d\n",i);
}
else
{
printf("%d\n",ans2);
for(int i=1; i<=m; ++i)
for(int j=1; j<=r[i]; ++j)
printf("col %d\n",i);
for(int i=1; i<=n; ++i)
for(int j=1; j<=b[1][i]; ++j)
printf("row %d\n",i);
}
return 0;
}
本文介绍了一个基于矩阵的游戏策略求解问题,目标是最小化操作次数使初始矩阵变为给定矩阵。通过从行或列减少元素的方式寻找最优解,并提供了一种有效的算法实现。



387

被折叠的 条评论
为什么被折叠?



