zjnu(1181)——石子合并
这道题算是最简单的区间dp了。。非常久之前写的,搞懂原理了就1A。
传送门: problem_id=1181">http://acm.zjnu.edu.cn/CLanguage/showproblem?problem_id=1181
状态方程定义:
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]);
然后利用三层for就好了。
for(int len=2;len<=n;len++){
for(int s=1;s<=n-len+1;s++){
int e=s+len-1;
f[s][e]=inf;
for(int k=s;k<=e-1;k++){
if(f[s][e]>f[s][k]+f[k+1][e]+sum[s][e])
f[s][e]=f[s][k]+f[k+1][e]+sum[s][e];
}
}
}
最重要的是这个循环,可是事实上也挺简单,首先枚举区间长度,齐次枚举起点s,当然这里每次都要对f[s][e]都初始化为正无穷(视题目情况而定),由于这里每一次的s与e都是不同样的。
然后第三层枚举的是k,k相当于跳板的作用,然后在里面进行dp就好了。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 111
#define inf 99999999
int f[maxn][maxn],sum[maxn][maxn],spone[maxn];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&spone[i]);
for(int i=1;i<=n;i++){
sum[i][i]=spone[i];
for(int j=i+1;j<=n;j++){
sum[i][j]=sum[i][j-1]+spone[j];
}
}
int min1=inf;
for(int len=2;len<=n;len++){
for(int s=1;s<=n-len+1;s++){
int e=s+len-1;
f[s][e]=inf;
for(int k=s;k<=e-1;k++){
if(f[s][e]>f[s][k]+f[k+1][e]+sum[s][e])
f[s][e]=f[s][k]+f[k+1][e]+sum[s][e];
}
}
}
if(min1>f[1][n]) min1=f[1][n];
for(int i=1;i<n;i++){
swap(spone[i],spone[i+1]);
for(int l=1;l<=n;l++){
sum[l][l]=spone[l];
for(int q=l+1;q<=n;q++){
sum[l][q]=sum[l][q-1]+spone[q];
}
}
for(int len=2;len<=n;len++){
for(int s=1;s<=n-len+1;s++){
int e=s+len-1;
f[s][e]=inf;
for(int k=s;k<=e-1;k++){
if(f[s][e]>f[s][k]+f[k+1][e]+sum[s][e])
f[s][e]=f[s][k]+f[k+1][e]+sum[s][e];
}
}
}
if(min1>f[1][n]) min1=f[1][n];
swap(spone[i],spone[i+1]);
}
printf("%d\n",min1);
}
/*
3
2 5 1
*/
zjnu(1181)——石子合并的更多相关文章
- zjnu 1181 石子合并(区间DP)
Description 在操场上沿一直线排列着 n堆石子. 现要将石子有次序地合并成一堆.规定每次仅仅能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.同意在第一次合并前对调一 ...
- RQNOJ 490 环形石子合并
题目链接:https://www.rqnoj.cn/problem/490 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一 ...
- codevs1048 石子合并
题目链接:http://codevs.cn/problem/1048/ 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代 ...
- 石子合并[DP-N3]
题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- 51Nod 1021 石子合并 Label:Water DP
N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有 ...
- BZOJ 3229: [Sdoi2008]石子合并
3229: [Sdoi2008]石子合并 时间限制: 3 Sec 内存限制: 128 MB提交: 497 解决: 240[提交][][] 题目描述 在一个操场上摆放着一排N堆石子.现要将石子有次序 ...
- nyoj 737 石子合并(一)。区间dp
http://acm.nyist.net/JudgeOnline/problem.php?pid=737 数据很小,适合区间dp的入门 对于第[i, j]堆,无论你怎么合并,无论你先选哪两堆结合,当你 ...
- BZOJ-3229 石子合并 GarsiaWachs算法
经典DP?稳T 3229: [Sdoi2008]石子合并 Time Limit: 3 Sec Memory Limit: 128 MB Submit: 426 Solved: 202 [Submit] ...
- BZOJ3229 石子合并
Description 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石 ...
随机推荐
- 【转】 C#获取当前程序运行路径的方法集合
[转] C#获取当前程序运行路径的方法集合 //获取当前进程的完整路径,包含文件名(进程名). string str = this.GetType().Assembly.Location; resul ...
- explicit的用法
http://blog.csdn.net/chollima/article/details/3486230
- 低效能的”where1=1”
网上有不少人提出过类似的问题:"看到有人写了where 1=1这种sql,究竟是什么意思?".事实上使用这种使用方法的开发者一般都是在使用动态数组的sql. 让我们想象例如以下的场 ...
- node 命令行输入控件 prompt.js
function print(){ console.log.apply(console , arguments) } var step ,_lstStp ,_onConfirmInput ,_ ...
- 【LeetCode】Palindrome Partitioning 解题报告
[题目] Given a string s, partition s such that every substring of the partition is a palindrome. Retur ...
- zzulioj--1707--丧心病狂的计数(水题)
1707: 丧心病狂的计数 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 237 Solved: 105 SubmitStatusWeb Board ...
- mysql导入数据,涉及到时间转换,乱码问题解决
表结构: drop table if exists `qi_an_log`;CREATE TABLE `qian_log` (`dt` LONG NOT NULL COMMENT '产生日期,格式yy ...
- C# Lambda && Linq
Lambda表达式在C#3.0加入,它是一个匿名函数,可用于创建委托或者表达式树类型,运算符为=>,读作"goes to",=>左侧是变量,右侧是表达式,变量类型可以自 ...
- 由ubuntu装好想到的
这篇不是技术文,有点唠叨的总结.不喜勿喷. 最近开始全面学ubuntu,一翻书回忆起本科没选但是去听了的Linux.当时看的还是楚广明的fedora教程,这多年过去综合很多人的说 法,fedora不稳 ...
- JavaScript学习——JS对象和全局函数
1. Array对象 数组的特点:长度可变!数组的长度=最大角标+1 2.Boolean对象 如果value 不写,那么默认创建的结果为false 3.Date对象 getTime()返回1970年1 ...