一类适合记忆化搜索的区间dp

https://www.luogu.com.cn/problem/P5752

https://codeforces.com/contest/598/problem/E

cf这个题考虑dp预处理,状态是三维的,转移是分割方案和所分块需要获得的巧克力数量。最后题目多次询问可以o(1)快速查询的

// Problem: E. Chocolate Bar // Contest: Codeforces - Educational Codeforces Round 1 // URL: https://codeforces.com/contest/598/problem/E // Memory Limit: 256 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h> using namespace std; #define ll long long # define int long long #define ull unsigned long long #define pii pair<int,int> #define baoliu(x, y) cout << fixed << setprecision(y) << x #define endl "\n" #define debug1(x) cerr<<x<<" " #define debug2(x) cerr<<x<<endl const int N = 35; const int M = 1e6 + 10; const int inf = 0x3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; int n, m,k; int dp[N][N][N*N]; int a[N]; //考虑区间dp,记忆化搜索 //提前预处理答案,O(1)查询 //30*30*900(状态)*(60*30)转移=48600000*30(1.2e8) //不会跑满,加上记忆化和行列地位对等的剪枝 int dfs(int x,int y,int cnt){ if(cnt==0||x*y==cnt)return 0; int &res=dp[x][y][cnt]; //res=1e18; if(res!=-1)return res; if(dp[y][x][cnt]!=-1)return res=dp[y][x][cnt]; res=1e18; for(int i=1;i<=x-1;i++){ int now=cnt; for(int c=0;c<=now;c++){ res=min(res,dfs(i,y,c)+dfs(x-i,y,now-c)+y*y); } } for(int i=1;i<=y-1;i++){ int now=cnt; for(int c=0;c<=now;c++){ res=min(res,dfs(x,i,c)+dfs(x,y-i,now-c)+x*x); } } dp[y][x][cnt]=res; return res; } void solve(){ cin>>n>>m>>k; cout<<dfs(n,m,k)<<endl; } signed main() { cin.tie(0); ios::sync_with_stdio(false); memset(dp,-1,sizeof dp); int t; cin>>t; // t=1; while (t--) { solve(); } return 0; }

NOI1999

典型的记忆化搜索区间dp,根据方差公式变形,判断每次转移是根据切割方式和选择继续在哪部分上切割,不要的那部分的方差贡献需要预处理二维前缀和快速查询

// Problem: 棋盘分割 // Contest: AcWing // URL: https://www.acwing.com/problem/content/description/323/ // Memory Limit: 10 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h> using namespace std; #define ll long long //# define int long long #define ull unsigned long long #define pii pair<int,int> #define baoliu(x, y) cout << fixed << setprecision(y) << x #define endl "\n" #define debug1(x) cerr<<x<<" " #define debug2(x) cerr<<x<<endl const int N = 17; const int M = 1e6 + 10; const int inf = 0x3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; int n, m; int a[N][N]; double avg=0; double get(int x1, int y1,int x2,int y2){ double res=a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1]; res-=avg; return res*res; } //只需要割k-1次 double f[N][N][N][N][N]; double dp(int k,int x1,int y1,int x2,int y2){ double &u=f[k][x1][y1][x2][y2]; if(u>=0)return u; if(k==m){ //不存在第m次切割,m-1次以后就满足要求,直接返回这个棋盘的贡献 return u=get(x1,y1,x2,y2); } double tmp=1e9; for(int i=x1;i<x2;i++){ tmp=min(tmp,dp(k+1,x1,y1,i,y2)+get(i+1,y1,x2,y2)); tmp=min(tmp,dp(k+1,i+1,y1,x2,y2)+get(x1,y1,i,y2)); // tmp=min(tmp,dp[k+1][x1][y1][i][y2]+get(i+1,y1,x2,y2)); // tmp=min(tmp,dp[k+1][i+1][y1][x2][y2]+get(x1,y1,i,y2)); } for(int i=y1;i<y2;i++){ tmp=min(tmp,dp(k+1,x1,y1,x2,i)+get(x1,i+1,x2,y2)); tmp=min(tmp,dp(k+1,x1,i+1,x2,y2)+get(x1,y1,x2,i)); // tmp=min(tmp,dp[k+1][x1][y1][x2][i]+get(x1,i+1,x2,y2)); // tmp=min(tmp,dp[k+1][x1][i+1][x2][y2]+get(x1,y1,x2,i)); } return u=tmp; } void solve(){ n=8; cin>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=8;j++){ cin>>a[i][j]; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ a[i][j]+=a[i-1][j]; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ a[i][j]+=a[i][j-1]; } } avg=(double)a[n][n]/(double)m; // cerr<<avg<<endl; memset(f,-1,sizeof f); //初始状态有一个盘 //当前已经对棋盘k-1次切割,有k个棋盘 //k次划分后选择的棋盘是 左上角为 x1y1,右下角x2y2 double ans=dp(1,1,1,n,n); // cerr<<ans<<endl; ans=sqrt(ans/(double)m); baoliu(ans,3); } int main() { cin.tie(0); ios::sync_with_stdio(false); int t; //cin>>t; t=1; while (t--) { solve(); } return 0; }

__EOF__

本文作者爱飞鱼
本文链接https://www.cnblogs.com/mathiter/p/18100543.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   potential-star  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示