有一个n行m列的网格蛋糕,上面有一些樱桃,求使得每块蛋糕上都有一个樱桃的切割最小长度
思路:dp。
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #define eps 1e-6 #define LL long long using namespace std; const int maxn = 100 + 5; const int INF = 10000000; int d[22][22][22][22]; int n, m, K, kase = 0;//樱桃数量 int cherry[22][22], sumv[22][22]; int cpu(int a, int b, int c, int d) { return sumv[b][d] - sumv[a-1][d] - sumv[b][c-1] + sumv[a-1][c-1]; } int dp(int begx, int endx, int begy, int endy, int cherrynum) { int& ans = d[begx][endx][begy][endy]; if(cherrynum == 1) return 0; if(ans != -1) return ans; ans = INF; for(int i = begx; i < endx; i++) if(cpu(begx, i, begy, endy) > 0 && cpu(begx, i, begy, endy) < cherrynum) ans = min(ans, dp(begx, i, begy, endy, cpu(begx, i, begy, endy))+dp(i+1, endx, begy, endy, cherrynum-cpu(begx, i, begy, endy))+endy-begy+1); for(int i = begy; i < endy; i++) if(cpu(begx, endx, begy, i) > 0 && cpu(begx, endx, begy, i) < cherrynum) ans = min(ans, dp(begx, endx, begy, i, cpu(begx, endx, begy, i))+dp(begx, endx, i+1, endy, cherrynum-cpu(begx, endx, begy, i))+endx-begx+1); return ans; } void init() { memset(d, -1, sizeof(d)); memset(cherry, 0, sizeof(cherry)); memset(sumv, 0, sizeof(sumv)); int x, y; for(int i = 0; i < K; i++) { cin >> x >> y; cherry[x][y] = 1; } for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) sumv[i][j] = sumv[i][j-1] + sumv[i-1][j] + cherry[i][j] - sumv[i-1][j-1]; } void solve() { printf("Case %d: %d\n", ++kase, dp(1, n, 1, m, K)); } int main() { //freopen("input.txt", "r", stdin); while(scanf("%d%d%d", &n, &m, &K) == 3) { init(); solve(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u014664226/article/details/46694699