合并石子
来源:互联网 发布:linux 打印debug日志 编辑:程序博客网 时间:2024/04/29 18:44
http://acm.nankai.edu.cn/p1137.html
只有相邻的石子才能合并成堆,十分类似矩阵连乘问题,这里是形成了环,另d[i][j] 表示从第i个元素开始,共j个石子堆的最小得分,c[i][j]表示最大考虑n<=100,n^2的复杂度可行,各种在处理环时不细心啊
// category: dp#include <stdio.h>#include <string.h>using namespace std;const int maxn=105;int n ;int d[maxn][maxn],c[maxn][maxn];int sum[maxn];int a[maxn];void solve(){for (int l=2;l<=n;++l){for (int i=0;i<n;++i){d[i][l]=99999999;c[i][l]=0;for (int j=1;j<l;++j){int s1,s2;int k=(i+j-1)%n;if (k<i) s1=sum[n-1]-sum[i-1]+sum[k] ;else if(i==0) s1=sum[k];else s1=sum[k]-sum[i-1];int r=(i+l-1)%n;if (r<k) s2=sum[n-1]-sum[k]+sum[r];else s2=sum[r]-sum[k];int ans1=d[i][j]+d[(i+j)%n][l-j]+s2+s1;int ans=c[i][j]+c[(i+j)%n][l-j]+s2+s1;d[i][l]=d[i][l]>ans1 ? ans1:d[i][l];c[i][l]=c[i][l]>ans ? c[i][l]:ans;}}}int min=d[0][n],max=d[0][n];for (int i=1;i<n;++i){ if (min>d[i][n]) min=d[i][n]; if (max<c[i][n]) max=c[i][n];}printf("%d\n%d\n",min,max);}int main(){while(~scanf("%d",&n)){memset(sum,0,sizeof(sum));scanf("%d",&a[0]);sum[0]=a[0];for (int i=1;i<n;++i){scanf("%d",&a[i]);sum[i]=sum[i-1]+a[i];}solve();}return 0;}
- 石子-石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 【石子合并】
- 合并石子
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 石子合并
- 合并石子
- 石子合并
- 合并石子
- vim 列编辑功能
- 向大牛看齐
- USACO/rockers 3.4.4 动态规划
- Javascript基础
- The Day the QA Department Died
- 合并石子
- mysql 数据库知识累积
- phpcms v9 之session配置
- 你的第一个Windows程序——写窗口过程
- while循环得到循环次数
- android.widget.TextView.setText()
- android 2D游戏开发,引擎设计(二)脚本思考
- ubuntu12.04安装ant
- java编码问题