問題描述
n個整數組成的乙個環,現在要從中取出m個數,取走乙個數字就不能取跟它相鄰的數字(相鄰的數不能同時取)。要求取出的數字的總和盡可能大,問這個最大和是多少? 如果無解,請輸出「error!」
輸入格式
第一行包含兩個正整數n、m。
第二行為n個整數ai。
輸出格式
僅乙個整數,表示所求結果。如果無解輸出「error!」,不包含引號。
樣例輸入
8 4
8 5 6 2 3 4 8 9
樣例輸出
我們先把每個數字以及它的編號拿入堆中。建大根堆。並記錄下每個數左右元素的編號。l[k],r[k]。
最後要輸出的答案是ans。初始化為0。
然後每次從堆裡面拿出堆頂元素,ans+這個堆定元素的值。
假設我們當前取出的堆頂元素的編號為k。我們現在新生成乙個數p[i]=p[l[k]]+p[r[k]]-p[k]。
編號為i的數左邊的數的編號我們賦為l[l[k]]。右邊的數賦為r[r[k]]。
然後r[r[k]]的左邊是i。l[l[k]]右邊是i。( 類似於鍊錶的操作)
ps:注意陣列範圍
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define maxn 200005
struct node;
bool
operator
<(node a,node b);
for(i=1;i<=n;i++)
l[1]=n;r[1]=2;temp.a=a[1];temp.x=1;q.push(temp);
l[n]=n-1;r[n]=1;temp.a=a[n];temp.x=n;q.push(temp);
for(i=2;i1;r[i]=i+1;temp.a=a[i];temp.x=i;
q.push(temp);
}tot=n;
for(i=1;i<=m;i++)
ans+=tmp.a;tot++;
a[tot]=a[l[tp]]+a[r[tp]]-a[tp];
mark[l[tp]]=mark[r[tp]]=mark[tp]=true;
r[l[l[tp]]]=l[r[r[tp]]]=tot;
l[tot]=l[l[tp]];r[tot]=r[r[tp]];
temp.a=a[tot]; temp.x=tot;
q.push(temp);
}cout
<}
題 貪心 神似DP NKOJ3102 取數
nkoj3102 取數 時間限制 20000 ms 空間限制 165536 kb 問題描述 n個整數組成的乙個環,現在要從中取出m個數,取走乙個數字就不能取跟它相鄰的數字 相鄰的數不能同時取 要求取出的數字的總和盡可能大,問這個最大和是多少?如果無解,請輸出 error 輸入格式 第一行包含兩個正整...
洛谷P1392 取數 堆
題目傳送門 在乙個n行m列的數陣中,你須在每一行取乙個數 共n個數 並將它們相加得到乙個和。對於給定的數陣,請你輸出和前k小的取數方法。輸入格式 第一行,三個數n,m,k。第2 n 1行,每行m個正整數 輸出格式 一行共k個數,代表在每一行取乙個數前k小的加和 輸入樣例 1 複製 3 3 2 1 2...
P1005 矩陣取數
看完題可能第一時間並沒有清晰的思路。讓我們一步一步的來考慮這道題目。題目中描述操作為每次從所有的行中選取,這樣做有些麻煩。仔細思考一下可以發現行與行之間互不干涉,所以我們可以對每行操作到底,最後統計答案。每行怎麼選取當然難不倒聰明的oier了,設f i j 表示某行從第i位到第j位的最優答案。轉移如...