传送门:https://s8pc-4.contest.atcoder.jp/tasks/s8pc_4_b#
日文题面:
時間制限 : 1sec / メモリ制限 : 256MB
配点:350 点
問題文
N 個の建物が左から右へと一直線上に並んでいます。左から i 番目の建物は色 i で塗られており、高さは現在 ai です。 高橋君は市長である。彼はカラフルなものが好きなので、左から見たときに K 色以上の色の建物が見えるという条件を満たしてほしいと思いました。
現在の状況から、建物の高さを増やすことができます。しかし、高さを 1 増やすごとに 1 円かかります。また、高さを減らすことはできません。
そのとき、高橋君の目的を達成するために必要な金額を求めなさい。
ただし、「建物 i が見える」とは、建物jの高さ ≥ 建物iの高さ (j<i) となるような j が存在しないのと同じものとします。
入力
Copy
N K a1 a2 a3 ... aN
出力
最小金額を 1 行に出力しなさい。
また、最後には改行を入れること。
制約
- 1≤K≤N≤15
- 1≤ai≤109
得点
小課題1 [120 点]
- N=K
小課題2 [90 点]
- N≤5
- ai≤7
小課題3 [140 点]
- 追加の制約はない。
入力例1
Copy
5 5 3949 3774 3598 3469 3424
出力例1
Copy
1541
建物の高さを左から順に 3949,3950,3951,3952,3953 とすると高橋君はすべての建物を見ることができます。
入力例2
Copy
5 3 7 4 2 6 4
出力例2
Copy
7
建物の高さを左から順に 7,8,2,9,4 とするとコスト 7 で目標を達成することができます。
英文题面:
Time limit : 1sec / Memory limit : 256MB
Max Score: 350 Points
Problem Statement
There are N buildings along the line. The i-th building from the left is colored in color i, and its height is currently ai meters.
Chokudai is a mayor of the city, and he loves colorful thigs. And now he wants to see at least K buildings from the left.
You can increase height of buildings, but it costs 1 yens to increase 1 meters. It means you cannot make building that height is not integer.
You cannot decrease height of buildings.
Calculate the minimum cost of satisfying Chokudai's objective.
Note: "Building i can see from the left" means there are no j exists that (height of building j) ≥ (height of building i) and j<i.
Input Format
Copy
N K a1 a2 a3 ... aN
Output Format
Print the minimum cost in one line. In the end put a line break.
Constraints
- 1≤K≤N≤15
- 1≤ai≤109
Scoring
Subtask 1 [120 points]
- N=K
Subtask 2 [90 points]
- N≤5
- ai≤7
Subtask 3 [140 points]
- There are no additional constraints.
Sample Input 1
Copy
5 5 3949 3774 3598 3469 3424
Sample Output 1
Copy
1541
The optimal solution is (height of buildings from the left) =[3949,3950,3951,3952,3953].
Sample Input 2
Copy
5 3 7 4 2 6 4
Sample Output 2
Copy
7
The optimal solution is (height of buildings from the left) =[7,8,2,9,4].
题目大意:给出一个含个数的序列,将某些数进行调整,各自加上某些正值,从而构造出一个从左到右的
项递增子序列;问要加的值的最小总和。
开始想到贪心,发现前面值得调整会影响后面的数;看到数据范围,果断搜索。
唯一的坑点是最后要输出一个空行,不然会判错;还有一开始初始化的INF要足够大。
代码:
#include<cstdio>
#include<cstring>
using namespace std;
int n,k;
long long ans;
long long a[16];
void dfs(int now,long long fee)
{
if (fee>=ans)
return;
int x=0;
int last=0;
for (int i=1;i<=n;i++)
if (a[i]>a[last])
{
x++;
last=i;
}
if (x==k)
{
if (fee<ans) ans=fee;
return;
}
last=0;
for (int i=1;i<now;i++)
if (a[i]>a[last])
last=i;
for (int i=now;i<=n;i++)
{
if (a[i]>a[last])
{
last=i;
continue;
}
long long b=a[i];
a[i]=a[last]+1;
dfs(i+1,fee+a[last]-b+1);
a[i]=b;
}
}
int main()
{
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%lld",&a[i]);
if (n==k)
{
long long ans=0;
for (int i=1;i<=n;i++)
if (a[i]<=a[i-1])
{
ans+=a[i-1]-a[i]+1;
a[i]=a[i-1]+1;
}
printf("%lld\n",ans);
return 0;
}
ans=15000000000;
dfs(1,0);
printf("%lld\n",ans);
}