fjnu2019二親善試合のタイトルF

###トピックのリンク###

 

効果の件名:

 

Zが存在N日間の選択、投資プログラムのm種類は、毎日の投資プログラムのいずれかで選択することができ、開始コイン手を有し、そのNように、X(手にコインの数が負であることはできない)の硬貨として何度も取り一日の終わりの後、Yにコインを取得します。

 

第二に、私自身の手の中のノードの数に基づいて、一日の終わりの後には、いくつかの補償金を取得する必要があり、一日の終わりの後に設定コインの数xを持って、その後、X> kで、デフォルトの場合、f(x)がコインを取得0。F [0]を確認してください〜F [k]は単調に増加しません。

 

この質問の元のタイトル:ブログの接続には  、お金の手のちょうど始まりは異なっています。

 

分析:

1は、その後、DP列挙日の状態、(、お金の翌日の手の数である)一日のスタートが所有するコインの数と最初の契約、および日投資するとき、全体のプロセスは、n個日間に分かれています。私たちは、一日の終わり後の朝に投資転送ではなく、状態遷移を行うために次の日一日の終わりの後の状態を払い戻しいたしますので。

図2は、それがセットDPとき[I] [j]が(日が補償されていない)は、i番目の日の完了後に投資を表し、jは手でコインを有し、硬貨の最大総数は、一日の終わりに返さN得ます。

3、その後、唯一の補償による補償から転送された日の後にコインの数で毎日開始について(より多くのお金があるとき、すなわち、手持ちのコインの数が発生します0以上〜kは0〜kの時間であり、左報酬を得ることを可能にした後)、ので、いくつかのコインを手に残りの日を通過する毎日の必要性の初めに、いくつかの補償、コインの数が始まり、今日であることを取得します。

図4は、一日のコインの数を取得した後、状態遷移における今日の投資を開始しました。何度でもための投資の数としては、その転送が完了するバックパックです。

5、のためならば投資した翌日の状態の手がj個の元(つまり、DP [I] [J])したとき 、 それは(J +投資コスト)のための日から手持ちのお金の投資を開始します、投資コストのコストからの転送後。そのため、投資コストがリターンvの最終日、wがあると仮定し、そこDP [I] [J] = DP [I] [J +は、W] + V、 バックパックを完了するために、最大値をとります。

図6は、コインの数は開始したが、上述したように、その日の残りのコインで初日から転送開始したことはできないので、それは最初の治療の最初の日を分離する必要があります。

7、初期化の問題: - 、彼らはすべての負の無限大を初期化するから、zのお金の手の最初の日を転送する必要必要がある論理的には、この問題は、最大、ゼロ魚に初期化し、すべてが、この問題の実際の重要性を確実にする必要性を要求DP次いで、[1]〜[Z]は値0 DP、そのDP転送を示し、手の最初の日からZ場合コインそこから転送されなければなりません。

8.最初の日、私たちは、すべての状態がこれを購入していない、その結果、次の日(つまり、最初の日に転送されます初日にものを購入するために必要とされなければならないことを意味列挙し、析出しているので状態)が渡されることはありませんし、次の日に転送します。私たちは答えを求めるときに、我々はまた、お金のn日かどうかを決定する必要があり、その結果、(結果的に最初の日とは、購入していない場合は、次の日には購入することができない最大値を向けるようになったことを意味する)より投資しないだろう。

 

注意点:

図1は、直接そのような場合、近接n³の複雑さ* K(Kは定数)上に行われれば、この質問は(もちろん人間の良心タイトル緩和時間)を3000msデータを有することになります。

2.完全にバックパックに列挙スキームの番号を削除し、原則を知る必要が時間の複雑さを軽減します。実際には、この原則がdp現在、この層は、状態遷移(詳細Baiduが所有またはグループを尋ねる)上で更新されている前から[I] [J]です。

図3に示すように、完全に異なる次元削減バックパックと、この共通の問題は、式DP分析移し、彼は後ろから転送されたことが見出されている(すなわち、DP [I] [J] + W jからjから転送されます)最適化する際に、我々は逆のバックパックの容量を列挙する必要があります。

 

いいえ最適化されたコードありません。

書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include < 文字列の.h>
 使用して 名前空間はstdを、
INT Z、N、M、K。
int型 DP [ 108 ] [ 2008 ];
int型の F [ 1008 ]。
構造体製品{
     int型A、B。
} A [ 108 ]。
int型のmain()
{
    scanf("%d%d%d%d",&z,&N,&M,&K);
    for(int i=0;i<=K;i++) scanf("%d",&f[i]);
    for(int i=1;i<=M;i++) scanf("%d%d",&A[i].a,&A[i].b);
    memset(dp,0x80,sizeof(dp));
    dp[1][z]=0;
    for(int w=1;w<=M;w++){
        for(int j=A[w].a;j<=2000;j++){
            for(int k=0;k<=j/A[w].a;k++){
                dp[1][j-k*A[w].a]=max(dp[1][j-k*A[w].a],dp[1][j]+k*A[w].b);
            }
        }
    }
    for(int i=2;i<=N;i++){
        for(int j=0;j<=K;j++) dp[i][j+f[j]]=max(dp[i][j+f[j]],dp[i-1][j]);
        for(int w=1;w<=M;w++){
            for(int j=A[w].a;j<=2000;j++){
                for(int k=0;k<=j/A[w].a;k++){
                    dp[i][j-k*A[w].a]=max(dp[i][j-k*A[w].a],dp[i][j]+k*A[w].b);
                }
            }
        }
    }
    int ans=z;
    for(int i=0;i<=2000;i++) ans=max(ans,dp[N][i]+i+f[i]);
    printf("%d\n",ans);
}

 

优化代码:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int z,N,M,K;
int dp[108][2008];
int f[1008];
struct Goods{
    int a,b;
}A[108];
int main()
{
    scanf("%d%d%d%d",&z,&N,&M,&K);
    for(int i=0;i<=K;i++) scanf("%d",&f[i]);
    for(int i=1;i<=M;i++) scanf("%d%d",&A[i].a,&A[i].b);
    memset(dp,0x80,sizeof(dp));
    dp[1][z]=0;
    for(int w=1;w<=M;w++){
        for(int j=2000;j>=A[w].a;j--){
            dp[1][j-A[w].a]=max(dp[1][j-A[w].a],dp[1][j]+A[w].b);
        }
    }
    for(int i=2;i<=N;i++){
        for(int j=0;j<=K;j++) dp[i][j+f[j]]=max(dp[i][j+f[j]],dp[i-1][j]);
        for(int w=1;w<=M;w++){
            for(int j=2000;j>=A[w].a;j--){
                dp[i][j-A[w].a]=max(dp[i][j-A[w].a],dp[i][j]+A[w].b);
            }
        }
    }
    int ans=z;
    for(int i=0;i<=2000;i++) ans=max(ans,dp[N][i]+i+f[i]);
    printf("%d\n",ans);
}

 

 

おすすめ

転載: www.cnblogs.com/Absofuckinglutely/p/12052225.html