日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pku 1191 棋盘分割 DP / 记忆化搜索

發(fā)布時間:2025/3/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pku 1191 棋盘分割 DP / 记忆化搜索 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://poj.org/problem?id=1191?

?題意:中文省略.

思路:黑說p116有講解,

主要的狀態(tài)轉(zhuǎn)移方程為

橫著切:?

dp[k][x1][y1][x2][y2] ?= min(dp[k - 1][x1][y1][mid][y2] + dp[1][mid][y1][x2][y2],dp[k - 1][mid][y1][x2][y2] + dp[1][x1][y1][mid][y2]); ? x1 + 1 <= mid < x2

豎著切:

dp[k][x1][y1][x2][y2] ?= min(dp[k - 1][x1][y1][x2][mid] + dp[1][x1][mid][x2][y2],dp[k - 1][x1][mid][x2][y2] + dp[1][x1][y1][x2][mid]); ?y1 + 1<= ?mid < y2

?

?

View Code?#include?<iostream>
#include?<cmath>
#include?<cstdio>
#include?<cstring>
#define?maxn?17
#define?N?8
using?namespace?std;
const?int?inf?=?99999999;

int?dp[maxn][9][9][9][9];
int?map[9][9];

int?getDP(int?k,int?x1,int?y1,int?x2,int?y2)
{
????int?mid;
????int?ans?=?inf;
????for?(mid?=?x1?+?1;?mid?<?x2;?++mid)
????{
????????ans?=?min(ans,dp[k?-?1][x1][y1][mid][y2]?+?dp[1][mid][y1][x2][y2]);
????????ans?=?min(ans,dp[k?-?1][mid][y1][x2][y2]?+?dp[1][x1][y1][mid][y2]);
????}
????for?(mid?=?y1?+?1;?mid?<?y2;?++mid)
????{
????????ans?=?min(ans,dp[k?-?1][x1][y1][x2][mid]?+?dp[1][x1][mid][x2][y2]);
????????ans?=?min(ans,dp[k?-?1][x1][mid][x2][y2]?+?dp[1][x1][y1][x2][mid]);
????}
????return?ans;
}
int?main()
{
????//freopen("d.txt","r",stdin);
????int?n,i,j,k;
????int?x1,y1,x2,y2;
????scanf("%d",&n);
????memset(map,0,sizeof(map));
????int?sum?=?0;
????//map存每個矩形的和
????for?(i?=?1;?i?<=?N;?++i)
????for?(j?=?1;?j?<=?N;?++j)
????{
????????scanf("%d",&map[i][j]);
????????sum?+=?map[i][j];
????????map[i][j]?+=?map[i][j?-?1]?+?map[i?-?1][j]?-?map[i?-?1][j?-?1];
????}
????//出事話dp將所有劃分成一個的求出來
????memset(dp,0,sizeof(dp));
????for?(x1?=?0;?x1?<?N;?++x1)
????for?(y1?=?0;?y1?<?N;?++y1)
????for?(x2?=?x1?+?1;?x2?<=?N;?++x2)
????for?(y2?=?y1?+?1;?y2?<=?N;?++y2)
????{
????????int?tmp?=?map[x2][y2]?-?map[x1][y2]?-?map[x2][y1]?+?map[x1][y1];
????????dp[1][x1][y1][x2][y2]?=?tmp*tmp;
????}
????//枚舉求解
????for?(k?=?2;?k?<=?n;?++k)
????for?(x1?=?0;?x1?<?N;?++x1)
????for?(y1?=?0;?y1?<?N;?++y1)
????for?(x2?=?x1?+?1;?x2?<=?N;?++x2)
????for?(y2?=?y1?+?1;?y2?<=?N;?++y2)
????{
????????dp[k][x1][y1][x2][y2]?=?getDP(k,x1,y1,x2,y2);
????}
????double?ans?=?(1.0*dp[n][0][0][8][8])/n?-?(1.0*sum*sum)/(n*n*1.0);
????printf("%.3lf\n",sqrt(ans));
????return?0;

?

?

記憶化搜索:

這里只要能夠推出狀態(tài)轉(zhuǎn)移方程,其實記憶化搜索就很好寫了。

?

View Code?#include?<iostream>
#include?<cmath>
#include?<cstdio>
#include?<cstring>
#define?maxn?17
#define?N?8
using?namespace?std;
const?int?inf?=?99999999;

int?dp[maxn][9][9][9][9];
int?map[9][9];

/*int?getDP(int?k,int?x1,int?y1,int?x2,int?y2)
{
????int?mid;
????int?ans?=?inf;
????for?(mid?=?x1?+?1;?mid?<?x2;?++mid)
????{
????????ans?=?min(ans,dp[k?-?1][x1][y1][mid][y2]?+?dp[1][mid][y1][x2][y2]);
????????ans?=?min(ans,dp[k?-?1][mid][y1][x2][y2]?+?dp[1][x1][y1][mid][y2]);
????}
????for?(mid?=?y1?+?1;?mid?<?y2;?++mid)
????{
????????ans?=?min(ans,dp[k?-?1][x1][y1][x2][mid]?+?dp[1][x1][mid][x2][y2]);
????????ans?=?min(ans,dp[k?-?1][x1][mid][x2][y2]?+?dp[1][x1][y1][x2][mid]);
????}
????return?ans;
}
*/
int?getS(int?x1,int?y1,int?x2,int?y2)
{
????return?map[x2][y2]?-?map[x1][y2]?-?map[x2][y1]?+?map[x1][y1];
}
int?DP(int?k,int?x1,int?y1,int?x2,int?y2)
{
????int?mid;
????if?(dp[k][x1][y1][x2][y2]?!=?0)?return?dp[k][x1][y1][x2][y2];//記憶的由來
????if?(k?==?1)//分割到最小取得值
????{
????????int?tp?=?getS(x1,y1,x2,y2);
????????dp[1][x1][y1][x2][y2]?=?tp*tp;
????????return?tp*tp;
????}
????int?ans?=?inf;
????//橫向切割
????for?(mid?=?x1?+?1;?mid?<?x2;?++mid)
????{
????????ans?=?min(ans,DP(k?-?1,x1,y1,mid,y2)?+?DP(1,mid,y1,x2,y2));
????????ans?=?min(ans,DP(k?-?1,mid,y1,x2,y2)?+?DP(1,x1,y1,mid,y2));
????}
????//縱向切割
????for?(mid?=?y1?+?1;?mid?<?y2;?++mid)
????{
????????ans?=?min(ans,DP(k?-?1,x1,y1,x2,mid)?+?DP(1,x1,mid,x2,y2));
????????ans?=?min(ans,DP(k?-?1,x1,mid,x2,y2)?+?DP(1,x1,y1,x2,mid));
????}
????dp[k][x1][y1][x2][y2]?=?ans;
????return?ans;
}
int?main()
{
????//freopen("d.txt","r",stdin);
????int?n,i,j;
????scanf("%d",&n);
????memset(map,0,sizeof(map));
????int?sum?=?0;
????//map存每個矩形的和
????for?(i?=?1;?i?<=?N;?++i)
????for?(j?=?1;?j?<=?N;?++j)
????{
????????scanf("%d",&map[i][j]);
????????sum?+=?map[i][j];
????????map[i][j]?+=?map[i][j?-?1]?+?map[i?-?1][j]?-?map[i?-?1][j?-?1];
????}
????memset(dp,0,sizeof(dp));
????int?tmp?=?DP(n,0,0,8,8);
????double?ans?=?(1.0*tmp)/n?-?(sum*sum*1.0)/(n*n*1.0);
????printf("%.3lf\n",sqrt(ans));
????return?0;

?

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/E-star/archive/2012/08/12/2634248.html

總結(jié)

以上是生活随笔為你收集整理的pku 1191 棋盘分割 DP / 记忆化搜索的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。