2019シミュレーションゲームレポートを解決する09ゲーム
タグ(スペースで区切っ):問題解決レポートForever_chen 2019年8月20日
カタログ・ラ~~
質問:テレポート
[の問題]
1日、夕暮れ光る突然どのように整数a1のシーケンスは、A2、...、遊びのシーケンスの順序は、関心をドロップしません。若いユニコーンのように、彼女は唯一の「単位変換」(単位シフト)操作を呼び出すことができます。言い換えれば、彼女はシーケンスの最後の要素は、その開始位置に移動したことがあります
。$$ A1、A2、...、AN→AN、A1、A2、...、AN - $$ 1
夕暮れを助けてください光沢の計算:この順序を並べ替えるために必要な操作の彼女の最小数はどのくらいですか?
[入力形式
整数n(^ 52≤n≤10)の最初の行の。
第二行は、N個の整数のA1、A2、...、(表し 1≤ai≤10^ 5)。
[出力形式]
シーケンスが順序付けされていない場合は、-1の出力
、または、それが光沢のある夕暮れソート必要な最小動作周波数と出力します。
|入力サンプル1 |サンプル出力1 |
| ------ | ------ |
| 2
2 1 | 1 |
| サンプル入力2 | サンプル出力2 |
|。1
。1 3 2 | -1 |
| サンプル入力3。 | 。サンプル出力3 |
| 2
1 2 | 0 |
- アルゴリズム分析[]
模拟
あなたがしたい場合はシーケンスをドロップしない特定のトピックを満たすために、我々は、列の順序番号に5 $があるだけで、$ 4、例を与えることができてしまう:$ 1,2,3,4,5; 5 、1,2,3,4- ,; 4,5,1,2,3、3,4,5,1,2、2,3,4,5,1 $
観察シーケンスが成立している、我々は見ることができます法律は、それがそこ2であるか、または順序付けられます $ N-X + 1 $(合計$配列を低下しない、および数を減少させない操作のシーケンスに変換される- $参照番号1 $ + $位置は、しかし、動作シーケンス)は、この法律がすでにある$ $ 1,2,3,4,5減少しないシーケンス、特殊な決意を必要と満足していません- この規則によれば、我々は決意方法を考え出すことができることは、我々は$ 5 $配列を上述のように、参照番号として、最小の数は、我々は参照番号として各配列$ 1 $は$ 3であるだろうことができる一連の数字であってもよいです$ケース
- 例えば1,2,3,4,5 $ $として第一の配列の$ $参照番号1、およびのみシーケンス全体のみ確立配列、$ 0、$出力(特別な判断を低下させない、$ N-X + 1にすることはできません$)
- 例えば$ 2,3,4,5,1 $、該当しない配列を得るために、参照番号の前にのみ配列、$ 0 $のそうでなければ出力として最後のシーケンスで$ 2 $ベンチマーク
3,4,5,1,2 $、我々ができ、シーケンスの途中で$ 3 $参照番号例えば、$ 5,1,2,3,4、4,5,1,2,3 、ベースライン前配列と配列の参照番号は、それぞれ降順未満ソート $ 3 $配列バック$ 2 $、$ 3 $続い$ 2 $、$ 1 $フロント$ 5 $の前に$ 5 $に$ 1 $上述したように、列比較を$ 4 $、我々は、Aは、入力シーケンスである(法律を遵守し、描くことができ、Bは、ソートされた行の配列であり、iは変更操作なし基準()の位置番号であり、jはベースラインまたはベースライン後の前の位置の数であります(前方または後方デクリメントインクリメントJ)):
旧J $の(参照番号満たす数- $):$ [J ] = Bは、$ [N-Iがj + 1 +]
参照カウントを満たした後に($ J ++ $):$ [J] = Bは、$ [N-Iがj + 1 +]- 注意:同じ番号が発生する可能性があり、こうした$ 2,3,4,1,1 $(参照番号が複数回表示されます)ので、私たちは、上記の方法でアクションを追加する必要がありますよう:限りの参照があるように、参照番号が複数、出会いの数、我々が与える操作のすべて、私たちが列をフォールバックすることはできません(操作の出力数)
A[给出序列ai] -->|排序后找到基准数| B(基准数b1)
B --> C{基准数的三种情况}
C -->|基准数在序列的第一位| D[满足整个序列为不下降序列]
C -->|基准数在序列的中间| E[基准数前后都是不下降序列且a和b序列中的数字满足关系]
C -->|基准数在序列的最后一位| F[满足基准数前序列为不下降序列]
D --> G{可以进行操作}
E --> G{可以进行操作}
F --> G{可以进行操作}
- [AC]コード
#include<bits/stdc++.h>
using namespace std;
int n,a[100010],b[100010],ans,x;
bool f=0,fg=0,fg2=0;
bool cmp(int x,int y) {
return x<y;
}
bool work(int i) {
bool f=0;
x=i;//x记录i的值(基准数的位置),在最后运算时用
if(i==1) {//基准数在序列的第一位
for(int j=i+1; j<=n; j++) {
if(a[j]!=b[j]) {
f=1;
break;
}
}
} else {
if(i==n) {//基准数在序列的最后一位
for(int j=i-1; j>=1; j--) {
if(a[j]!=b[j+1]) {
f=1;
break;
}
}
} else {//基准数在序列的中间
for(int j=i-1; j>=1; j--) {//对基准数前的数字进行判断
if(a[j]!=b[n-i+j+1]) {
f=1;
break;
}
}
for(int j=i+1; j<=n; j++) {//对基准数后的数字进行判断
if(a[j]!=b[j-i+1]) {
f=1;
break;
}
}
}
}
return f;
}
int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n,cmp);
for(int i=1; i<=n; i++) {//特判,当输入的序列就为不下降序列时
if(a[i]!=b[i]) {
fg=1;
}
}
if(fg==0) {
printf("0");
return 0;
} else {
for(int i=1; i<=n; i++) {
if(a[i]==b[1]) {
if(work(i)==0) {//只要一个基准数满足
printf("%d",n-x+1);
return 0;
}
}
}
printf("-1");
}
//system("pause");
return 0;
}
質問2:食べ物を注文します
[の問題]
新年が来て、レレは「チョコレートのレストランと呼ばれる有名なレストラン、。開かれた
私は、CIの野菜を販売されていた最初のこのレストランでの提供n個の野菜を、コピーはレストランの受注から生産された愛ディスプレイ上で、クライアントが訪問今日レストランを選ぶだろうがM、j番目のお客様は、レストラン場合。、食品DJの最初のコピーtiの種類を買うJ + 1と第一の顧客が購入するだけで、j番目の顧客の後に来るだろうこの人は、その後、彼はまだ彼のニーズを満たすために食糧の最低価格を持って購入する現在の最小最小食べ物が会議まで、買った後、彼は十分な食料を購入していきます、最初は、Ti野菜を育てるための需要を満たすことができません自分のニーズ(ヒント:すべての料理は、関係なく、どのように多くの料理の前の、完売しているが、それでも自分のニーズを満たすことができない、そして直接出力0、レストランがこの人の要求を満たしていないため、顧客は怒って去る場合レストランでは、出力に、この人の総消費量を人々のニーズを満たすことができる場合は、顧客が。)食べて、王の食事を支払うことはありません。
短い皆で彼が望んでいる食品の種類を購入しなければならない、ではない量 彼は数を購入するために必要になるまで、最低価格を購入するときは、もちろん、すべての料理は、自分のニーズを満たすことができない購入している場合、出力は0ではあなたの仕事は一人一人の総消費量を計算することである。
[入力フォーマット】
入力された整数n及びmの最初の行(1≤n、^ 5m≤10) 、皿の異なる種類の総数と顧客の総数を表す。
第2の行入力nは正の整数であり、A1、A2、...、( ^ 71≤ai≤10)、AIは野菜のi番目の初期数。表す
第3の入力列nは正の整数C1、C2、...、CN( ^ 61≤ci≤10)を、ciはIを表し野菜価格。
以下Mライン、ライン顧客の注文ごとに。j番目の行の2つの正の整数でTJ入力とDJ(1≤tj≤n、1≤dj≤10^ 7) 、各j番目クライアント種類となっており、食品の量
【形式】出力
消費者の顧客の出力コモン-M出力ラインj番目の行、j番目の総数(これは、現在の顧客の要求出力0を満たしていない)。。
|サンプル入力1 |サンプル出力例1 |
| ------ | ------ |
|。5. 8
8 4. 5. 6. 7. 5 1 2。
6 3 3 2 6 3 2 2
2 8
1 4。
4. 7。
3. 4。
6 10 | 22である
24
14
10
39 |
| サンプル入力2 | サンプル出力2 |
| 6 6
6 6 6 6 6 6
6 666 6666 66666 66 666666
。1. 6
2. 6
。3。6
。4。6
。5. 6
6 66 | 36
396
3996
39 996
399 996
0 |
| サンプル3入力 | サンプル出力を3 |
| 6 6
6 6 6 6 6 6
6 666 6666 66666 66 666666。
1. 6。
2 13をれる
3. 6。
4. 11。
5。6。
6 6 | 36
11058
99 996
4333326
0
0 |
[解説]サンプル
サンプル:クライアントは、次の5つの方法を提供します:
1区は、第2のユーザに6部の野菜を供給し、この時間は満たすことができません彼の要求は、とても安い第四及び第六野菜1部1部の野菜を買いました。価格6 3 + 1 2 + 1 2 = 22。図8は、野菜{8,0,2,0,4,4,7,5}の残りの数です。
2.第2の顧客は、野菜の第4の部分に設けられています。コスト4 6 = 24。残りの数の{4,0,2,0,4,4,7,5}。
3.第三の顧客が完売4つの野菜ので、野菜4の7部を必要とするので、部品は、野菜及び野菜の4つの6 8 3部品を提供することができます。4費用2 + 3 2 = 14。残りの数の{4,0,2,0,4,0,7,2}。
第4の顧客には、レストランが2部3部2と8野菜の野菜を提供し、3つの野菜の4部を必要とします。コスト2 3 + 2 2 = 10。残りの数の{4,0,0,0,4,0,7,0}。
レストランの顧客が野菜7 7部、最初の野菜の3部を提供するように、第5の顧客は、6〜10重量部の野菜、第完売野菜を必要とします。コスト7 3 + 3 6 = 39。残りの数の{1,0,0,0,4,0,0,0}。
サンプルII:すべての顧客サービス、その順序に従って、最後のクライアントを除いて、彼は怒って左と支払いなし。例えば、第2の顧客は第2の部分6野菜を必要とするので、コストは66であり、6 = 396。
サンプルIII:一部の顧客はサービスのための彼らの受注を得ることはできません。例えば、第二のクライアント13の第2の部分は、野菜を必要とする、それだけで3つの6野菜、野菜1 4部の最も高価な部品を購入することができ、コストは66だった 6 + 666 6 + 6666 1 = 11058
- アルゴリズム分析[]
模拟
私たちは、二重のその価格に応じてソートされたキーワード皿を入力することができ、それらは、元$(ID)のシリアル番号を記録リストと同じように生き残るために$、行の良い順- 注意:レストランでは、顧客の需要を満たすために送信しなかった場合、顧客は皿の残りの部分を食べますが、(私は本当に、なぜ怒らなければならない、払っていないかわからない)払っていません
- [AC]コード
#include<bits/stdc++.h>
using namespace std;
long long n,m,cnt;//cnt 总共还有多少菜
struct forever {
long long c,num,nxt,id;//c价格,num数量,nxt下一个比a[i].c大的菜的id,id 序号
} a[100010];
bool cmp1(forever x,forever y) {
return x.c<y.c;
}
bool cmp2(forever x,forever y) {
return x.id<y.id;
}
int main() {
scanf("%lld%lld",&n,&m);
for(int i=1; i<=n; i++) {
scanf("%lld",&a[i].num);
a[i].id=i;
a[i].nxt=1e9;//用nxt记录最大的菜
cnt+=a[i].num;
}
for(int i=1; i<=n; i++) {
scanf("%lld",&a[i].c);
}
sort(a+1,a+1+n,cmp1);//按照菜的价格排序
for(int i=1; i<n; i++) {//将下一个比a[i].c大的菜的id记下
a[i].nxt=a[i+1].id;
}
int p=a[1].id;//p是目前存在的最便宜的菜的id
sort(a+1,a+1+n,cmp2);//排回菜原始的id顺序
while(m--) {
long long iid,inum,ans=0;
scanf("%lld%lld",&iid,&inum);
if(cnt<inum) {//如果菜不够,就输出0
cnt=0;
printf("0\n");
continue;
}
cnt-=inum;
if(a[iid].num>=inum) {//如果顾客的菜够,就将菜的数量乘顾客所需的数量
a[iid].num-=inum;
ans=a[iid].c*inum;
} else {//如果顾客的菜不够
ans+=a[iid].num*a[iid].c;//买完需要的菜
inum-=a[iid].num;
a[iid].num=0;
while(a[p].num<inum) {//找下一个价格最小的菜
inum-=a[p].num;
ans+=a[p].c*a[p].num;
a[p].num=0;
p=a[p].nxt;//找下一个价格最小的菜
}
ans+=inum*a[p].c;
a[p].num-=inum;
}
printf("%lld\n",ans);
while(p!=1e9 &&a[p].num==0)p=a[p].nxt;//如果当前菜刚好用完,找出现有的最小的菜
}
//system("pause");
return 0;
}
質問3:蹄プリント
[問題の]
彼は今、高い需要の配列を示すときのシーケンスのバランスをとるための牛は非常に満足、しかしベリーズは、各シーケンスは、同じ左括弧の数が続かなければならない前に左括弧を依頼することですが、右括弧の数。例えば:(((())))、それは完璧なバランス配列です。
農場の上を歩いて、彼は地面に蹄プリントを見つけベリーズ1日には、ファームはNである各蹄プリントの小さな箱を持って、N個の正方形。ベリーズは、彼は蹄のプリントに来た各小箱は完璧を形成することができるように、各が、一歩を移動するには上または下または左または右にすることができ、場所の正方形の左上隅から開始したいですシーケンスのバランス。もちろん、ベリーズは、どんな小さなボックスで複製することはできません。
Nでベリーズを助けてください N.で完璧な正方形の最長シーケンスの長さを見つけるために
[入力形式
正の整数Nの最初の行の、ファームのサイズ。
Nの文字の次のNライン、行くマークのN * Nの正方形の分布を表しています。
[]出力形式は、
完全最長シーケンスの長さを表すだけライン整数であるため、完全な配列(例えば、右括弧が開始位置である)、出力0存在しない場合。
|入力サンプル1 |サンプル出力1 |
| ------ | ------ |
|。4
(()) ()((
(()(
))))| 8 |
- アルゴリズム分析[]
dfs
私たちは「完璧なバランスシーケンス」内の数字を見つける必要がありますので、最初の検索の全てと思うの:検索は、左括弧の左括弧に番号$になる場合、$のDFS $、我々は、座標から$(1,1)$を検索を開始することができます検索は、検索と右括弧の左括弧の数が同じ答え$ $ maxの操作で、最終的に最大値を返したときに、右ブラケット右側ブラケット番号$ rを+ 1 $になりますL + 1 $、- 注:場合は$(1,1)$は、$ 0 $(左カッコから「完璧なバランスシリーズの開始)右括弧をそのまま出力することができますです
- [合意]データ範囲
- $ 2 <= N <= 5 $; 説明:サンプル、牛は、配列がそのようなものである歩く:
$$ 1())$$
$$ 2)(($$
$$ 345($$
$$ 876)$$ - [AC]コード
#include<bits/stdc++.h>
using namespace std;
int n,ans;
int go1[4]={1,0,-1,0},go2[4]={0,1,0,-1};
char ch[10][10];
bool f[10][10];
void dfs(int x,int y,int l,int r) {
if(l==r) {//当搜索到的左括号和右括号数量相同时
//cout<<ans<<endl;
ans=max(l*2,ans);//将搜索到的右括号和左括号的数量加起来(l+r或l*2或r*2就是‘平衡的完美序列’的长度)
return;
}
for(int i=0; i<=3; i++) {
if(x+go1[i]>0 && x+go1[i]<=n && y+go2[i]>0 && y+go2[i]<=n && f[x+go1[i]][y+go2[i]]==0) {//在满足不会超出图的边界的情况下且路没有被走过
f[x+go1[i]][y+go2[i]]=1;
if((ch[x+go1[i]][y+go2[i]]=='(')&&!r) {//搜索到左括号
dfs(x+go1[i],y+go2[i],l+1,r);//左括号数量++
}
if(ch[x+go1[i]][y+go2[i]]==')') {//搜索到右括号
dfs(x+go1[i],y+go2[i],l,r+1);//右括号的数量++
}
f[x+go1[i]][y+go2[i]]=0;
}
}
}
int main() {
scanf("%d",&n);
f[1][1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>ch[i][j];
}
}
if(ch[1][1]==')'){//如果(1,1)为右括号
printf("0");//直接输出0
return 0;
}
dfs(1,1,1,0);
printf("%d",ans);
//system("pause");
return 0;
}
質問4:造園
[問題]
ファーマージョンは最近、彼の庭を美化することを決定しましたが、彼は汚れの多くを輸送する必要があります。そのNブロックの花壇による庭。泥のi番目のブロックは、いつそこに愛花壇初期量。美化の目的のために、土は私の花壇のブロック数Aiはバイなったようなものでなければなりません。
ジョンは3つのオプションがあります:まず、彼は花壇に土壌に任意の、X-費用をユニットを購入することができ、2番目、彼は花壇の土壌の単位、Yの費用から取り外すことができ、第三に、彼| IJ | i番目の単位ブロックの花の庭の土は、j番目のブロックの花畑、* Zのコストに輸送することができます。
ジョンに最低限必要な支出を達成するための計算コストを助けてください。
[入力形式
最初の行の4つの整数であるN、X、Y、Z。
二つの整数、それぞれ、AiとBiの次のNライン。
[出力形式]
のみ一行最小コストを表す整数。
サンプル入力1 | サンプル出力1 |
---|---|
4 100 200 1 1 4 2 3 3 2 4 0 |
210 |
[注]
データ範囲:1 <= N <= 100,0 <=愛、バイ<= 10,0 <= X、Y、Z <= 1000。説明:土壌のすべては、土壌の1つのユニット200の費用で、直接除去される第四の花畑、及び第1の花壇から4つの花畑土壌の残りの3つのユニットから除去されなければなりません。
- アルゴリズム分析[]
dp
粘土の数など、私たちは、それぞれが別々の花の庭の土を持っています。この質問は、$ 1,2,2,3,3,3,4,4,4,4 $に$ 3,4 $となります。図1は4は、4つを表し、2は第二のブロック花壇を2つの土ユニット2、3は第3花壇土ユニット3を示すを示し、花壇土1つの単位を表します第四大地の花の庭は4つの単位を有します。操作は、目的の文字の中に、次に実行すべきキャラクタを移動さ- $ 1 $文字を挿入します。$ F [I、J] = F [I、J-1] + X $([iが、J-1]が$ Iにターゲット文字列$ 1の$部分を文字列$ 1を表し、F $ )J-1 $同じ部分は、同じのターゲット文字列Jの$部分に$ I $ 1から$ 1、この時点で入力した文字列を作るために、それは、文字を挿入する必要があるの$ Xの$支払うこと
- 2. $ $文字$ Fを削除[I、J]はF [I-1、j]は+ Yの$ =
- 文字を移動し、任意の文字の$ F [I、J]はF [I-1、J-1] +のZ *のABS([I] -b [J])$ $ A $が入力され=変換する$ 3 $文字列、$ B $すなわち、ターゲット文字列
- 初期設定:入力文字列が空である、I $の客観的検討のために同じ文字列長に挿入X $を
、対象の文字列が同じ元の文字列の長さを省略することが、空になったとき、コストは$ Iである Yの$
- [AC]コード
#include<bits/stdc++.h>
using namespace std;
int x,y,z,n,xx,yy,a[1001],b[1001],f[1001][1001],l,ll;
int main() {
scanf("%d%d%d%d",&n,&x,&y,&z);
for (int i=1; i<=n; i++) {
scanf("%d%d",&xx,&yy);
for (int j=1; j<=xx; j++){
a[++l]=i;
}
for (int j=1; j<=yy; j++){
b[++ll]=i;
}
}
memset(f,0x7f,sizeof(f));
for (int i=0; i<=l; i++){//初始化,代价为i*y
f[i][0]=i*y;
}
for (int i=0; i<=ll; i++){//初始化,代价为i*x
f[0][i]=x*i;
}
for (int i=1; i<=l; i++){
for (int j=1; j<=ll; j++){
f[i][j]=min(f[i-1][j-1]+z*abs(a[i]-b[j]),min(f[i-1][j]+y,f[i][j-1]+x));
}
}
printf("%d",f[l][ll]);
//system("pause");
return 0;
}