DPその他の質問

T1:物事の消失

カジュアルワーキング:

  $ Ftiasch $ N $は、記事がボリュームある$ W_1、W_2、...、W_N $を持ちます$。そのため、彼女の過失により、$ iは、失われたアイテムを$。「残りの$ Nを使用するには - $ Xの$バックパックの量で満たさ1 $オブジェクトを、いくつかの方法は、それがあるのですか?」 - これは、古典的な問題です。

  彼女は、(i、x)は$カウント$と呼ば答え、すべては私が= Nの$ $ 1 <= xと<= M $ A $カウント(I、x)は$フォームを<= <$ 1を取得したいです。 

  入力フォーマット:

  第$ 1 $ラインの2つの整数$ N $ $ $および$ M $ $(1≤M×10 3 2≤^)$(1≤N 2×10 ^ 3≤)、アイテムの数と最大容積。

  $ 2 $行:$ N $の整数$ W_1、W_2、...、W_N $、記事のボリューム。

  出力フォーマット:Mの$行列×の$ N、$カウント(I、X)$最後の数字

ソリューション:

  

コード:

1の#include <cstdioを>
 2の#include <CStringの>
 3の#include <cstdlib>
 4  の#define $ 3111
 5  の#define INT長いロング
 6  使って 名前空間STD。
7  int型、M、N、K、T、DP [$]、V [$]、G [$]。
図8は、 メイン(){符号付き
 9      のscanf(" %のLLDの%のLLD "、&​​N、&M)を、    
10      のために(登録をint i = 1 ; iは= N <; ++ I)のscanf(" %のLLD "、&Vを[I])。
11      DP [ 0 ] =1 ;
12      のために(登録をint i = 1 ; iが<= N; ++ I)
 13          のため(登録INT J = M; J> = V [i]は、 - J)DP [J] =(DP [J] + DP [JV [I])%10 14      のために(登録をint i = 1 ; iが<= N ++ {i)を
 15          (登録INT J = 0 ; J <= M; ++ j)のG [j]はDP [J]%= 10 16          のために(登録INT G [j] =(G [J] -g [JV [I])%; J <= M ++ J J = V [i])と10 17          (レジスタint型J = 1 ; J <= M; ++ j)は 
 18              のprintf(" %のLLD "、(G [j]が%10 + 10)%10)。プット("" );
19      }
 20 }
コードの表示

 

T2:牙ボボのトウモロコシ畑

カジュアルワーキング:

  歩きながら、彼の農場で牙ボボは、彼が突然、トウモロコシ畑の行は非常に美しいではありませんがわかりました。

  $ N $トウモロコシ株の合計のこの行は、その高さが変化します。

  牙ボボは単調に美しいのシーケンスを減らす考えていないので、彼はその後、単調減少列を構成していないトウモロコシの高さの残りの部分を作り、秋のトウモロコシの除去の美しさを破壊し、トウモロコシの誇張のいくつかを置くことにしました。

  牙ボボは、$ 1 $高さの単位を誇張すべてのトウモロコシの範囲を範囲を選択することができ、彼は最高$ K $回この操作することができます。トウモロコシトウモロコシを引っ張ると外れのセットを選択することができます。

  Q.どのくらいのエネルギーが美しいトウモロコシの列を形成するために、トウモロコシのほとんどの株を残しました。

  入力フォーマット:

  最初の行は、トウモロコシ及び実行することができるどのように多くの操作までの行数を表す$ 1 $ 2 $ $整数の$ n $、$ K $を含んでいます。

  $ 2 $線は$ I $トウモロコシ株高さの$ a_iを$の左から右に$ I $の数は、トウモロコシの行を表し、n個の整数を含みます。

  出力フォーマット:出力する$ $整数1、残りのトウモロコシの最大数。

ソリューション:

  この問題は、小さな貪欲有する:ノードの動作x個で使用する場合、数nとして右終点ノードが必ずしも悪いとなるように。

  (ポイントは、次に、n個のノード、およびyノードで適切ではない場合)

  这道题一开始只能想到 $\Theta(n^2k^2)$ 的暴力,交上去才发现一个小测试点也没有。。。

  在 $\Theta(n^2k^2)$ 的暴力中,有一个十分显然的 dp 式:(边转移边更新答案)

$\sum\limits_{i=1}^{n}\sum\limits_{j=0}^{k}dp[i][j]=\sum\limits_{l=1}^{i-1}\sum\limits_{r=0}^{j-1}\max(dp[l][r])+1$

  我们发现在等式右侧,我们找的是一个矩阵的最大值,可以想到用二维树状数组来维护。

 

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #define int long long
 4 #define $ 505
 5 using namespace std;
 6 int n,k,dp[$*20][$],a[$*20],tr[$*20][$],ans,maxx;
 7 inline int max(int x,int y){    return x>y?x:y;    }
 8 inline void add(int x,int y,int add){
 9     for(register int i=x;i<=maxx+k;i+=i&(-i))
10         for(register int j=y;j<=k+1;j+=j&(-j)) tr[i][j]=max(tr[i][j],add); 
11 }
12 inline int ask(int x,int y,int ans=0){
13     for(register int i=x;i>=1;i-=i&(-i))
14         for(register int j=y;j>=1;j-=j&(-j)) ans=max(tr[i][j],ans);
15     return ans;
16 }
17 signed main(){
18     scanf("%d%d",&n,&k);
19     for(register int i=1;i<=n;++i) 
20         scanf("%d",&a[i]), maxx=max(maxx,a[i]);
21     for(register int i=1;i<=n;++i){
22         for(register int j=k;j>=0;--j){
23             dp[i][j]=ask(a[i]+j,j+1)+1, ans=max(ans,dp[i][j]);
24             add(a[i]+j,j+1,dp[i][j]);
25         }
26     }
27     printf("%d\n",ans);
28 }
View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #define int long long
 4 #define $ 501
 5 using namespace std;
 6 int n,k,dp[$*20][$],a[$*20],tr[$*21][$],ans,maxx;
 7 inline int max(int x,int y){    return x>y?x:y;    }
 8 inline void add(int x,int y,int add){
 9     for(register int i=x;i<=maxx+k;i+=i&(-i))
10         for(register int j=y;j<=k+1;j+=j&(-j)) tr[i][j]=max(tr[i][j],add); 
11 }
12 inline int ask(int x,int y,int ans=0){
13     for(register int i=x;i>=1;i-=i&(-i))
14         for(register int j=y;j>=1;j-=j&(-j)) ans=max(tr[i][j],ans);
15     return ans;
16 }
17 signed main(){
18     scanf("%d%d",&n,&k);
19     for(register int i=1;i<=n;++i) 
20         scanf("%d",&a[i]), maxx=max(maxx,a[i]);
21     for(register int i=1;i<=n;++i){
22         for(register int j=0;j<=k;++j) 
23             dp[i][j]=ask(a[i]+j,j+1)+1, ans=max(ans,dp[i][j]);
24         for(register int j=0;j<=k;++j) add(a[i]+j,j+1,dp[i][j]);
25     }
26     printf("%d\n",ans);
27 }
View Code

 

T3:拦截导弹

题干:

  某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度、并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其拦截的导弹的飞行速度也不能大于前一发。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

  在不能拦截所有的导弹的情况下,我们当然要选择使国家损失最小、也就是拦截导弹的数量最多的方案。但是拦截导弹数量的最多的方案有可能有多个,如果有多个最优方案,那么我们会随机选取一个作为最终的拦截导弹行动蓝图。

  我方间谍已经获取了所有敌军导弹的高度和速度,你的任务是计算出在执行上述决策时,每枚导弹被拦截掉的概率

  输入格式:

  第一行包含一个正整数 $n$,表示敌军导弹数量;

  下面 $n$ 行按顺序给出了敌军所有导弹信息:

  第 $i+1$ 行包含 $2$ 个正整数 $h_i$ 和 $v_i$ ,分别表示第 $i$ 枚导弹的高度和速度。

  输出格式:

  第一行为一个正整数,表示最多能拦截掉的导弹数量;

  第二行包含 $n$ 个 $0$ 到 $1$ 之间的实数,第 $i$ 个数字表示第 $i$ 枚导弹被拦截掉的概率(你可以保留任意多位有效数字)。

题解:

  

Code:

 

T1:

题干:

 

题解:

 

Code:

 

 

T1:

题干:

 

题解:

 

Code:

 

 

T1:

题干:

 

题解:

 

Code:

 

 

おすすめ

転載: www.cnblogs.com/OI-zzyy/p/11272928.html