問題の意味を理解します
サンタクロースの合計\(M \)クッキーは、完全な部品作製した\(N \)子供たちを。
各子供は貪欲と、貪欲子のi番目の次数有する\(Gを[I] \) 。
そこにもし\([i]が\)ビスケットの子どもの数は、最初よりも取得するには、\(私は\)子供とより、最初の\(私は\)子供たちが持っています\(G [i]が\回 [I ] \)不満。
与えられた\(N、M \) 、およびシーケンス\(G \) 、サンタクロースは彼がそれぞれの子が少なくともビスケットに割り当てられているような分布パターンを手配するように依頼し、すべての子どもたちの不満の最小合計。
入力形式
最初の行は二つの整数N、Mを含有します
2行目は、N個の整数が含ま\(G_1 \) 〜\(G_N \を)。
出力フォーマット
最初の行は、怒りの最小の整数の和を表します。
出力することができるいずれもの各種プログラム、場合Nのスペースで区切られた整数の2行目は、それぞれの子は、割り当てられたクッキーの数を表します。
データ範囲
\ [30 \ 1 \ N、\\\\ N \ M \ 5000 \\\\ 1 g_i \ 10 ^ 7 \\\\ \ \]
サンプル入力:
3 20
1 2 3
出力例:
2
2 9 9
レポートの問題解決
問題の意味を理解します
\(M \)ビスケット、得\(N \)の子供を、それぞれの子は貪欲を有しており、\(G [I] \) 、および嫉妬値\([I] \) 、もし\( [I] \)よりもビスケット子供の数\(私は\)とより多くの、それは恨みを生成します\(G [i]のを\回 [I] \)
最小要件の不満。
分析的思考
予備的な状態
子供の数は、クッキーを受け取った、と発行されたクラッカーは、私たちのダイナミックな計画段階でなければなりません。
しかし、私たちは、子供が必然的に生産怒りを見つけ、他の子どもたちが約受け取るビスケットの数。
\ [S [I] = \始める{事例} \ mathcal A [I] \タイムズG [I] \クワッドA [I] > 0 \\\\ \ mathcal 0 \クワッド [i]の端\ = 0 \\\\ {ケース} \\\\ S [i]は、子i番目の生成意味怒り\]
貪欲な最適化
私たちは、その状態のデザイン動的計画法を見つけ、出て来てほしいことは難しいことではありません。
しかし、我々は、この状態は、デザインを知っている見つけた場合でも、当社は、動的プログラミング遷移方程式を起動することはできません。
子供の不満は、状況の変化に応じて製造され、我々は出てこないと思うことはありません。姉妹の心は、このようなAです
私たちは、何かをする必要がありますか?
実際には、我々が見つかりました。貪欲な子供たちの大度は、より多くのビスケットを与えられるべきであるということ。
そこで、我々はの欲に従う大量注文に小さなを、次にクッキーの数は、それぞれの子は貪欲の程度に応じて取得しなければならない、降順。
もっと貪欲人々は、より多くのあなたは、ビスケットを取得します。もっときれい姉妹、求婚者
だから、クッキーの数は、単調に減少しています。
伝達方程式
私たちは、特定の表現の状態について設定することができます。
\ [I、Jの合計が不満とビスケットの最小値を割り当てられる前に、F [i]が[j]が子供のように表される。\]
次に転換の状態を。
\ [A [I + 1] = \ mathcal \ {ケース}始める[I + 1] = iはクワッドCNTを\ [I + 1] <CNT [I] \ クワッドI子供彼の前のクッキーよりも、クラッカー数は単調減少\\\\ \ mathcal A [I + 1である \ [I]] \クワッドCNT [I + 1] = cntのクワッドは、 どのように多くの子供たちビスケット、彼以上の前で知らない、決定することは困難である\\\\ \エンド{例} \\\\ CNTは、[ i]ははi番目の子は\]を取得クッキーの数を表し
、現在の問題がある、のが不明な状況に対処するために行かせ、最終的に前でそれよりもどのように多くの子供たちのクッキー。
等価変換
- あなたは私たちの現在の言うなら最初の\(私は\)子供の手の中にクッキーの数よりも多い\(1 \)の言葉を。
よると、クッキーの数単調に減少している、描画することができます
クッキーの数は\\\\列の最小数以上であるのi番目の子を取得するので、私の子供たちのビスケットは、GE 1 \\\\を\される前に、[我々の手を\値を1より大きく、そして他の値が存在する必要があります。1. \\より大きい\]
配布\(jは\)するクッキーの前に(私は\)\与えることと等価、実際には、子供を\(JIに\)にビスケットを前に\(私は\)子供たちを。
少しを得るためにすべての子供の同等。
理由は\([i]が\)すべての子供たち、ので、変更されていない多くの子供の数よりも、彼らはビスケットの数を変更していない、比較的論理関係の木が変更されました。
- あなたは、i番目の子が唯一のビスケットであると言うなら
我々だけでするかを選択できます列挙一つだけビスケットを取得する方法多くの子供たち、そして確かに多くありません。
\ [F [i]の[J] =分が\開始{事例} \ mathcal F [i]が[JI] \\\\ \ mathcal MIN_ {0 \ルK < I} {F [K、J(IK)] + K * \ sum_ {P = K + 1} ^ {I} {G [P]}} \\\\ \端{ケース} \\\\ \]
コード分析
#include <bits/stdc++.h>
using namespace std;
#define fir(i,a,b) for(int i=a;i<=b;i++)
#define int long long
const int N=110;
const int M=5100;
int n,m,i,j,k,f[N][M],s[N],g[N],a[N][M],b[N][M],ans[M],c[N];
int cmp(int a,int b)
{
return g[a]>g[b];
}
void print(int n, int m)
{
if (n==0)
return;
print(a[n][m],b[n][m]);
if (a[n][m] == n)
{
fir(i,1,n)
ans[c[i]]++;
}
else
fir(i,a[n][m]+1,n)
ans[c[i]] = 1;
}
signed main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
fir(i,1,n)
cin>>g[i],c[i]=i;
sort(c+1,c+1+n,cmp);
memset(f,0x3f,sizeof(f));
f[0][0]=0;
fir(i,1,n)
{
s[i]=s[i-1]+g[c[i]];
fir(j,i,m)
{
f[i][j]=f[i][j-i];
a[i][j]=i;
b[i][j]=j-i;
fir(k,0,i-1)
{
if (f[i][j]>f[k][j-(i-k)]+(s[i]-s[k+1-1])*k)
{
f[i][j]=f[k][j-(i-k)]+(s[i]-s[k+1-1])*k;
a[i][j]=k;
b[i][j]=j-(i-k);
}
}
}
}
cout<<f[n][m]<<endl;
print(n,m);
fir(i,1,n)
cout<<ans[i]<<' ';
cout<<endl;
return 0;
}