加载中...

神奇宝贝大军

题目:

下面是平平无奇的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;

}
posted @ 2022-09-22 20:18  biubidio  阅读(49)  评论(0)    收藏  举报