UVA10891
2015-10-23 21:13
197 查看
/* 题意:n 个数 AB两个人轮流从左或右端取连续的数, 每个人都按最优策略取,A先取,问最后A 比 B 多多少 。 区间DP。 用f[i][j]表示区间 i-j 能取的数的总和是多少, 如果从左端取,f[i][i+k]=max(f[i][i+k], (sum[i+k]-sum[i-1])-f[i][j]); 其中j∈[i,i+k) 。 则右端, f[i][i+k]=max(f[i][i+k], (sum[i+k]-sum[i-1])-f[j][j+k]); 其中j∈[i+1,i+k] . 再与取一整段比较取最优。 辣么,A比B多 f[1] - (f[1] -sum ) 即 2 * f[1] - sum */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int sum[110],a[110]; int f[110][110]; int main() { int n; while(scanf("%d",&n)!=EOF && n) { memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } int s=0; memset(f,-0x3f,sizeof(f)); for(int i=1;i<=n;i++) f[i][i]=a[i]; for(int k=1;k<n;k++) for(int i=0;i+k<=n;i++) { s=sum[i+k]-sum[i-1]; for(int j=i;j<i+k;j++) f[i][i+k] = max(f[i][i+k], s-f[i][j]); for(int j=i+1;j<=i+k;j++) f[i][i+k] = max(f[i][i+k], s-f[j][i+k]) ; f[i][i+k] = max(s,f[i][i+k]); } printf("%d\n", 2 * f[1] - sum ); } return 0; }
相关文章推荐
- scp命令
- 地图定位
- 在xcode中修改整个项目名
- Android沉浸式状态栏实现
- nmap与zmap的使用
- 关 于 yum rpm 的 类 习 题
- 克鲁斯卡尔算法(kruskal)(并查集的简单应用)
- 【JAVA知识】HashTable和HashMap的区别,并简述Hashmap的实现原理
- oVirt介绍及安装记录
- Delphi 实现任务栏多窗口图标显示(使用WS_EX_APPWINDOW风格)
- 初学Java的HelloWorld以及常见问题
- 功能测试
- 各种排序算法稳定性的总结!!!
- CGridCtrl 添加button (CGridCellButton类)
- iOS消息传递机制
- c++学习笔记(九):运算符重载进阶
- 迅雷是怎么下载的
- 黑马程序员——Java 基础:静态
- Andriod异步消息处理机制解析
- PPT基础与进阶