动态规划(入门,滚动数组,记录的都是状态):SWUSTACM-1010 魔兽争霸之最后的反击
题目:
1010: 魔兽争霸之最后的反击
Time Limit: 1000 MS Memory Limit: 65536 KB
Description
相传人族与兽族对峙了很久,双方均受到了重创,兽族趁人类没有能力发起大规模进攻之时突然袭击,想一次彻底打败人族。人类为了生存,无论老幼伤病,全部参战,兵分两路抗敌。
由于体质不同,我们以血量表示一个人的战斗力,现在给你所有人的血量,请你把人类分成战斗力最接近的两部分。注意,战斗力要最接近,不然,人族会因你而战败呦!
Input
第一行为一个整数n(1<=n<=36),表示人族的总人数。以下的n行每行一个整数,表示一个人的血量mi(即战斗力),其中1<=mi<=400.
Output
只有一行,包含两个数,即人族的每部分兵的血量总和,较小的一个值放在前面,两个数用空格分隔。
Sample Input
3
20
32
35
Sample Output
35 52
Source
SWUST
解题心得:
1、可以直接价将最大的战斗值/2,然后动态规划就行了。在规划的过程中状态有几种转移的方法。注意此题记录的都是状态(只有false和true),因为记录的是状态所以开的数组直接是bool类型就可以了,第一维是记录的物品的个数,第二维记录的是在选择第k个物品(人族的群数)的时候有多少种可能的重量(战斗力)。当可以达到这个重量的时候将这个重量记录为true。
第一种:
就是很简单的记录人群的数量和总的战斗力,直接给代码.
关于核心的动态规划解释一下:第k件物品,可以选择不装入,所以选择第k件物品的重量就是和第k-1个相同物品的状态相同。也可以选择装入,装入就必须第前一个状态【k-1】的 j-t[j] 要是true才可以转移到这个状态。
#include<bits/stdc++.h>
using namespace std;
bool dp[40][16000];//只是记录的状态bool就可以了,甚至bitset也可以;
int t[40];
int main()
{
int n;
int sum ;
while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
sum = 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i]);
sum += t[i];
}
dp[0][0] = 1;
for(int i=1;i<=n;i++)
{
for(int j=sum;j>=0;j--)
{
for(int k=1;k<=n;k++)
dp[k][j] = dp[k-1][j] | dp[k-1][j-t[k]];//这个是核心算法
}
}
for(int i=sum/2;i>=0;i--)
{
if(dp[n][i])
{
printf("%d %d\n",i,sum-i);
break;
}
}
}
}
#include<bits/stdc++.h>
using namespace std;
bool dp[2][16000];
int t[40];
int main()
{
int n;
int sum ;
while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
sum = 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i]);
sum += t[i];
}
dp[0][0] = 1;
int now;
for(int i=1;i<=n;i++)
{
for(int j=sum;j>=0;j--)
{
if(j >= t[i])
dp[i%2][j] = dp[(i+1)%2][j] | dp[(i+1)%2][j-t[i]];
else
{
if(dp[(i+1)%2][j])
dp[i%2][j] = 1;
}
}
now = i;//用来记录最后的那个数组,写的好弱智;
}
for(int i=sum/2;i>=0;i--)
{
if(dp[now%2][i])
{
printf("%d %d\n",i,sum-i);
break;
}
}
}
}
第三种:开一个一维数组直接转移就可以了
其实思想也很简单,这个状态转移不是从前面一次到后面转移,而是从后面往前面转移,所以后面的状态不会影响前面的状态,直接转移就可以了。
#include<bits/stdc++.h>
using namespace std;
bool dp[16000];
int t[40];
int main()
{
int n;
int sum ;
while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
sum = 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i]);
sum += t[i];
}
dp[0] = 1;
for(int i=1;i<=n;i++)
for(int j=sum;j>=0;j--)
{
dp[j] = dp[j] | dp[j-t[i]];
}
for(int i=sum/2;i>=0;i--)
{
if(dp[i])
{
printf("%d %d\n",i,sum-i);
break;
}
}
}
}
动态规划(入门,滚动数组,记录的都是状态):SWUSTACM-1010 魔兽争霸之最后的反击的更多相关文章
- 【动态规划】滚动数组的求解(C++)
虽然接触动态规划算法已经有一段时间,给一个01背包问题,能够做到一个表格简单粗暴下去,然后求得结果,但心里总觉得对这个算法理解十分不到位,抱着对算法的热爱,网上很多大牛的算法思维实在让我佩服的五体投地 ...
- POJ_1159 Palindrome (线性动态规划+滚动数组)
题意是说,给定一个字符串,问至少还需要插入多少个字符才能使得该字符串成为回文字符串. 这道题一开始做的时候用了一个简单的动态规划,开了一个5000*5000的数组,用递归形式实现,代码如下: 其中d[ ...
- HDU-1024 Max Sum Plus Plus 动态规划 滚动数组和转移优化
题目链接:https://cn.vjudge.net/problem/HDU-1024 题意 给n, m和一个序列,找m个不重叠子串,使这几个子串内元素和的和最大. n<=1e6 例:1 3 1 ...
- POJ-1038 Bugs Integrated, Inc. (状压+滚动数组+深搜 的动态规划)
本题的题眼很明显,N (1 <= N <= 150), M (1 <= M <= 10),摆明了是想让你用状态压缩dp. 整个思路如下:由于要填2*3或者3*2的芯片,那么就要 ...
- NOIP 2006 金明的预算方案(洛谷P1064,动态规划递推,01背包变形,滚动数组)
一.题目链接:P1064 金明的预算方案 二.思路 1.一共只有五种情况 @1.不买 @2.只买主件 @3.买主件和附件1(如果不存在附件也要运算,只是这时附件的数据是0,也就是算了对标准的结果也没影 ...
- 2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组)
2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组) https://www.luogu.com.cn/problem/P2516 题意: 给定字符串 \(S\) ...
- 动态规划+滚动数组 -- POJ 1159 Palindrome
给一字符串,问最少加几个字符能够让它成为回文串. 比方 Ab3bd 最少须要两个字符能够成为回文串 dAb3bAd 思路: 动态规划 DP[i][j] 意味着从 i 到 j 这段字符变为回文串最少要几 ...
- 【动态规划】【滚动数组】【bitset】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem J. Terminal
有两辆车,容量都为K,有n(10w)个人被划分成m(2k)组,依次上车,每个人上车花一秒.每一组的人都要上同一辆车,一辆车的等待时间是其停留时间*其载的人数,问最小的两辆车的总等待时间. 是f(i,j ...
- 【Java】【滚动数组】【动态规划】UVA - 11137 - Ingenuous Cubrency
滚动数组优化自己画一下就明白了. http://blog.csdn.net/u014800748/article/details/45849217 解题思路:本题利用递推关系解决.建立一个多段图,定义 ...
随机推荐
- SpringBoot | 第八章:统一异常、数据校验处理
前言 在web应用中,请求处理时,出现异常是非常常见的.所以当应用出现各类异常时,进行异常的捕获或者二次处理(比如sql异常正常是不能外抛)是非常必要的,比如在开发对外api服务时,约定了响应的参数格 ...
- EditPlus常用操作
EditPlus注册码在线生成 http://www.jb51.net/tools/editplus/ 随意填写个用户名,生成对应的密码就可以使用editplus了 EditPlus常用快捷键 编代码 ...
- asp.net后台调用前台js代码
为了通过ajax异步获取数据,我通过使用jquery的$(function{})方法,在页面加载时发送ajax请求,获取相关的数据.但是遇到了一个问题,当我发送的ajax请求需要根据传过来的URL参数 ...
- JavaSE_3_面向对象
1.wait方法底层原理 wait是object中的方法,可以暂停线程,会释放对象锁,不像sleep方法,线程休眠期依然持有锁,通过调用notify或notifyAll方法唤醒线程. lock.wai ...
- 可视化工具Navicat的使用/pymysql模块的使用
一.可视化工具Navicat的使用 1.官网下载:http://www.navicat.com/en/products/navicat-for-mysql 2.网盘下载:http://pan.baid ...
- 微信小程序tabBar 不显示底部菜单的原因和解决方法
1,书写,正确书写时tabBar,不要写成tabbar!!! 2,当创建新工程时,app.json中Pages配置是这样的 ,,[图1], 注意:微信小程序里面的json文件时不能注释的,图中只是给读 ...
- linux书籍推荐
<Linux/Unix设计思想> 图书将Unix与Linux的原理有效地结合起来,总结了Unix/Linux软件开发中的原则.在保留了第1版中Unix方面的内容的同时,强调了Linux和开 ...
- 新客户上云 - 来自 Azure 技术支持部门的忠告
本课程内容是来自 Azure 中国技术支持团队对新客户上云的忠告. 对于上云的新用户,Azure 技术支持部门有如下忠告: 1. 时刻关注并理解以下网站的变动来优化资源配置,更新设计方案. Azure ...
- RF的一些技术知识
1. dBm 定义的是 miliwatt(毫瓦特).0 dBm=1mw: dBw 定义 watt.0 dBW = 1 W =1000 mw = 10lg(1000/1)dBm=30dbm. dB ...
- web调试的一些小技巧
1.不带缓存的刷新,用于刷新css或者js:Ctrl+F5 待续...