神奇宝贝大军
题目:

下面是平平无奇的O(2^n)算法吖
#include<iostream>
using namespace std;
int ans=0;
int n;
int arr[100]= {0};
void f(int sum,int pos,int num)
{
if(pos>n)
{
if(sum>ans) ans=sum;
}
else//进行0/1处理
{
f(sum,pos+1,num);//不加入该数
if(num%2==1)
{
sum+=arr[pos];
}
else
{
sum-=arr[pos];
}
f(sum,pos+1,num+1);//加入该数
}
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>arr[i];
}
f(0,1,1);
cout<<ans;
}
/*
7
1 2 5 4 3 6 7
*/
再分析
1.大军总人数一定为奇数。
2.由于索引号的选择不能有逆序对,所以将ans的子集一定为两大数夹小数的形式。
3.考虑最大堆(?),先确定最大数,再分往前、往后(?)
4.以战斗力为y轴的折线图中,答案以V或者W或WW的形式出现,最终战斗力为差值之和。
……
一种O(n^2)写法:
f(result,pos+1,num+1);相当于将pos位的战力加入
pos++,继续循环,相当于跳过该战力
#include<iostream>
using namespace std;
int ans=0;
int n;
int arr[100]= {0};
void f(int sum,int pos,int num)
{
int result;
while(pos<=n)
{
if(num%2==1)
{
result=sum+arr[pos];
}
else
{
result=sum-arr[pos];
}
if(result>ans) ans=result;
f(result,pos+1,num+1);
pos++;
}
}
int main()
{
freopen("C:\\in.txt","r",stdin);
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>arr[i];
}
f(0,1,1);
cout<<ans;
}

浙公网安备 33010602011771号