1504 积木城堡
貌似这个题可以用暴力来做?
万物皆可暴力
哈哈哈哈
好了开始切入正题
他灵机一动,想出了一个巧妙的改造方案。他决定从每一个城堡中挪去一些积木,使得最终每座城堡都一样高。为了使他的城堡更雄伟,他觉得应该使最后的城堡都尽可能的高
所以这肯定就是一个动态规划
看dp的必备:
状态表示
动态转移动态转移
初始状态初始状态
首先,dp[i][j]表示前i块积木是否能到达高度j
#include<iostream>
#include<cstdio>
#include<algorrithm>
#include<string>
#include<cstring>
using namespace std;
int n,len,min_high = 2e9,w[105],ans[10005];
// w数组为每一城堡积木的高度
//ans数组为达到高度i的个数
bool dp[10005];
int main()
{
cin >> n; //n个城堡
for(int k=1;k<=n;k++)//每一个城堡
{
memset(dp,0,sizeof(dp));//以免前一个影响当前城堡
int cnt=0,high=0;//cnt为积木个数,high为高度
while(1)
{
cin >> len; //输入len
if(len == -1) break;
w[++cnt] = len;//存储高度
high += len;//计算总高度
}
dp[0]=1;//dp初始
for(int i=1;i<=cnt;i++)//枚举每一个积木
for(int j=high;j>=w[i];j--)//倒序枚举容量
dp[j] |= dp[j-w[i]];//因为p是01的,所以用|来,也有背包的意思
min_high = min(min_high,high);//取最低的高度
for(int i=high;i>=1;i--) // 检查一下能否达到高度
if(dp[i] == 1) ans[i]++;//到达高度就标记
}
for(int i = min_high;i>=1;i--)//检查哪一个高度能到达
if(ans[i] == n)
{
cout << i;// 输出
return 0;//遇见能输出的就直接输出
}
cout << "0"<<endl;
return 0;
}