zoj1234 chopsticks 经典dp
2016-02-12 17:41
162 查看
经典的dp题,题目大意:给出需要的组合数量和一些筷子长度,每个组合要求 a<=b<=c ,然后求所有组合的 (a-b)^2 的最小和。给出的筷子长度已经是非降序的了,有一个需要自己判断的点是:每个组合的 a、b 都是连续的,如何证明?(我也不知道TAT 网上也没找到证明过程)。 然后是观察这道题有没有dp性质,至于具体怎么判断我现在还没有形成条件反射,看了网上的题解以后,才找出状态 和 状态转移方程。
状态: dp[i][j], 表示第 i 根筷子 到 第 n 根筷子 有 j 个组合时的最小状态。
状态转移方程: dp[i][j]=min( dp[i+1][j] , dp[i+2][j-1] + (a[i]-a[i+1])^2 ); 选择这两个状态中的较小值,就是看要不要把第 i 根筷子 与 第 i+1 根筷子作为a+b,计算结果当然是当前最小状态。(这里我是自己手动模拟计算了以后才搞明白。。深深怀疑自己的智商)。
这道题用 int 可以搞定,数组不要开太大了。
以下是代码:
状态: dp[i][j], 表示第 i 根筷子 到 第 n 根筷子 有 j 个组合时的最小状态。
状态转移方程: dp[i][j]=min( dp[i+1][j] , dp[i+2][j-1] + (a[i]-a[i+1])^2 ); 选择这两个状态中的较小值,就是看要不要把第 i 根筷子 与 第 i+1 根筷子作为a+b,计算结果当然是当前最小状态。(这里我是自己手动模拟计算了以后才搞明白。。深深怀疑自己的智商)。
这道题用 int 可以搞定,数组不要开太大了。
以下是代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; int a[5002]; int dp[5002][1008]; int doub(int x) { return x*x; } int main() { int T; scanf("%d",&T); while(T--){ int k,n; memset(a,0,sizeof(a)); memset(dp,0,sizeof(dp)); scanf("%d%d",&k,&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); k+=8; dp[n-2][1]=doub(a[n-2]-a[n-1]); for(int i=n-3;i>=1;i--) for(int j=1;j<=k;j++){ if(n-i+1<3*j) break; //如果当前包含的筷子数量小于要求组合的数量 则直接加入下一根筷子。 if(n-i+1==3*j) dp[i][j]=dp[i+2][j-1]+doub(a[i]-a[i+1]); //如果恰好等于,则把 第 i 根 与 第 i+1 根筷子作为 a、b加入组合。 else dp[i][j]=min( dp[i+1][j] , dp[i+2][j-1]+doub(a[i]-a[i+1]) ); } printf("%d\n",dp[1][k]); } return 0; }
相关文章推荐
- tomcat-闪退和启动两个tomcat解决方法
- 类装载器读取properties资源文件
- 从初识Linux到离不开系列(四)循序渐进
- Linux环境下使用V4L2+opencv以MJPEG格式读取USB摄像头并实时显示
- 用十条命令在一分钟内检查Linux服务器性能
- [爬虫系列(二)]爬取豆瓣读书Top250,并保存每本书
- Docker多主机网络通信详解
- POJ 2642 The Brick Stops Here(01背包问题)
- JSF导出excel文件文件名使用中文,支持linux
- Educational Codeforces Round 7 D. Optimal Number Permutation 构造题
- ubuntu 搭建(编译)生产力版的LNMP环境
- linux系统常用命令-整理
- POJ 2627 Gopher and hawks(bfs)
- Windows环境Apache,Tomcat集群,动静分离,负载均衡
- 海淘联想电脑必备网站(第7通道和第8通道)
- linux 通过设置配置文件修改mysql的默认编码
- POJ 2610 Dog & Gopher(水~)
- 编译asterisk时报*** termcap support not found (on modern syst
- Linux NUMA优化(1)
- Shell排序的递增序列