1 条题解
-
0
这道题就是一个二维前缀和再加一个dfs遍历全部横切的情况然后找到最小切数的题,看了发的题解才明白,
太菜了太菜了👀️#include using namespace std; const int N=1010; const int M=12; char g[M][N]; 读入的数组 int sum[M][N];求二维前缀和的数组 int a[M];记录的横切面第几刀切到第几行 int n,m,k; 行列条件 int ans=M*N;初始化答案,最多全部行全部列 bool check(int cnt,int l,int r) { a[cnt+1]=n;把最后一行加上去判断 for(int i=1;i<=cnt+1;i++) { int x1=a[i]; int x2=a[i-1];用当前这刀和上一刀当做两个横切面 int t=sum[x1][r]-sum[x1][l]-sum[x2][r]+sum[x2][l];这里和学的二维前缀和有一点出入,这是因为我们不要分割线上的奶所以都没加减一; if(t>k) return false;如果不满足条件return false } return true;这是所有的分割块都满足 } void solve(int cnt) { int tot=cnt;切的刀数首先加上横着切的刀数 int l=0;记录上一个纵向分割线 for(int r=1;r<=m;r++)遍历所有的列寻找最小刀数 { if(!check(cnt,l,r)) { l=r-1;把r的前一列当作分割线,也就是这一块不要第r-1列的奶了 tot++;刀数++ if(!check(cnt,l,r))再检查一遍,不要了后是否满足,还不满足则直接pass掉这一种横切刀数的情况 { return ; } } } ans=min(ans,tot); return ; } void dfs(int u,int cnt)寻找所有的横切刀数的情况 { if(u==n)找到头了,开始解决问题 { solve(cnt);这里的a[]就已经存好cnt刀了 return ; } dfs(u+1,cnt);到下一个行数 a[cnt+1]=u;第cnt+1刀切的第u行 dfs(u+1,cnt+1);到下一行,并且存了一刀 return ; } int main() { cin>>n>>m>>k; for(int i=1;i<=n;i++) { cin>>g[i]+1; } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+g[i][j]-'0'; } } dfs(1,0); cout<ans<<endl return 0; }
信息
- ID
- 20941
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 85
- 已通过
- 25
- 上传者