codevs3002 石子归并 3
2018-06-17 21:13:25来源:未知 阅读 ()
有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。
第一行一个整数n(n<=3000)
第二行n个整数w1,w2...wn (wi <= 3000)
一个整数表示最小合并代价
4
4 1 1 4
18
数据范围相比“石子归并” 扩大了
也没啥好说的,
就是四边形不等式优化
证明我也不会
丢个博客链接
http://blog.csdn.net/noiau/article/details/72514812
#include<cstdio> #include<cstring> const int MAXN=1e5+10,INF=1e8+10; using namespace std; inline char nc() { static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin)),p1==p2?EOF:*p1++; } inline int read() { char c=nc();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();} return x*f; } int dp[3001][3001],sum[MAXN],s[3001][3001]; int main() { #ifdef WIN32 freopen("a.in","r",stdin); #else #endif int N=read(); for(int i=1;i<=N;i++) sum[i]=read(),sum[i]+=sum[i-1],s[i][i]=i; for(int i=N;i>=1;i--) { for(int j=i+1;j<=N;j++) { int mn=INF,mnpos=0; for(int k=s[i][j-1];k<=s[i+1][j];k++) { if(dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1] < mn) { mn=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]; mnpos=k; } } dp[i][j]=mn; s[i][j]=mnpos; } } printf("%d",dp[1][N]); return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 序列归并 2020-02-19
- MergeSort(归并排序)原理及C++代码实现 2020-01-14
- 重写二路归并排序 2019-09-23
- 论分治与归并思想 2019-08-16
- 石子合并问题--直线版 HRBUST - 1818 2019-08-16
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash