一つの動的なプログラミングトレーニング

動的なプログラミングについて

https://www.luogu.org/problem/P2577

分析:

まず、この質問ではありません貪欲ソートDP

次いで、データ範囲<= 200は、それだけであってもよいDP

私はそれらの簡単作ってみるべきだと考えて、この質問を考えて速い遅いが食べDafanを上面

そして、すべてのため、合計時間Dafanは、確かです

誰もが夕食の手配を終えたどんなにはとても多くの時間を費やすだろうと

したがって、我々は最高でなければならないスローフードの表面のみを考えます

しかし、二つのウィンドウがあり、この時間は、どのように必要なDPを配置します

  • [I、J] F個々のキューIを記録する前に、jがある場合に最初のチーム最大使用時間。

  • 記録しない第2チームの状態によって起動することができる理由は、チームへの第一の状態です。

  • 計算を簡単にするために、作るために推奨される使用プレフィックスをし、それを維持し、ときに、第2チームを計算するために、よりシンプルにすることができます。

  • その後、我々はこの方程式を得ました:

    最初のキューを追加する場合には:F [I、J] =分([-I 1、JA [I] .X] F [I、J]、MAX(F、J + A [I] .Y)) ;

    現在の最小値は、時間と人との個人的な時間の最大時間です

    同様に第2チームを追加します

    F [I、J] =最大 ([I-1、j]は、[I]・Y + B [i]は-J F) ここで、i個々のラインのためのB [i]を使用する合計時間前

    しかし、200 * 40,000は少し大きいようで、次元削減聖歌!

    ライン上の次元削減と同様のバックパック

    STDによるコード:

#include<bits/stdc++.h>
using namespace std;
struct lsg{int x,y;}a[1000];
int n,f[400001],sum,ans,b[1000];
bool pd(lsg x,lsg y){return x.y>y.y;}
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    for (int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
    sort(a+1,a+1+n,pd);memset(f,10,sizeof(f));f[0]=0;
    for (int i=1;i<=n;i++)b[i]=a[i].x+b[i-1];
    for (int i=1;i<=n;i++){
            for (int j=sum;j>=0;j--){
                f[j+a[i].x]=min(f[j+a[i].x],max(f[j],a[i].y+j+a[i].x));//将i加入第一个队列
                    f[j]=max(f[j],a[i].y+b[i]-j);//将i加入第二个队列
                }
            sum+=a[i].x;
        }
    ans=1e9;
    for (int i=1;i<=sum;i++)ans=min(ans,f[i]);
    cout<<ans<<endl;
}

おすすめ

転載: www.cnblogs.com/wzxbeliever/p/11622442.html