【CodeForces - 349B】Color the Fence (貪心,填數)
題幹:
Igor has fallen in love with Tanya. Now Igor wants to show his feelings and write a number on the fence opposite to Tanya's house. Igor thinks that the larger the number is, the more chance to win Tanya's heart he has.
Unfortunately, Igor could only get v liters of paint. He did the math and concluded that digit d
Help Igor find the maximum number he can write on the fence.
Input
The first line contains a positive integer v (0 ≤ v ≤ 106). The second line contains nine positive integers a
Output
Print the maximum number Igor can write on the fence. If he has too little paint for any digit (so, he cannot write anything), print -1.
Examples
Input
5
5 4 3 2 1 2 3 4 5
Output
55555
Input
2
9 11 1 12 5 8 9 10 6
Output
33
Input
0 1 1 1 1 1 1 1 1 1
Output
-1
題目大意:
在牆上用一定量的油漆塗數字,儘量使塗出來的數字大。輸入v是我擁有的油漆量,然後下一行九個數字告訴你塗每個數字所需要的油漆量。
解題報告:
這題顯然是個貪心,,問題就在於貪心正確性的證明。這題在青理工邀請賽的時候有過一個類似的題目也是貪心填數字。也是用類似的思想。
首先用最小值來判斷位數,那麼答案肯定是這個位數的,那麼我們來看在位數確定的情況下有沒有可能改變最優解。我們最開始的寫法也是可以改變最優解的,那就是把最後一位去掉然後看這一位可不可以填入別的數字,填的時候要滿足後面的用最小值還可以填上。。然後就貪心就行了,,注意要判斷a[j] > n 啊,不然後面那個if不就成負數了(其實這樣寫是無所謂的但是如果把minn除過來這麼寫的話就會出問題,比如-2/5本來是-(0.4)應該向下取整成-1但是因為優先順序的問題,就成0了,,於是可能就把不能算上的情況算上了。因為你之所以可以直接用除法取整就是因為除法是預設向下取整啊但是在負數中就不是向下取整了所以就會出現很多問題,,所以保險起見還是少用除法多用加減乘、、、)
AC程式碼:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e6 + 5;
int a[22],ans[MAX];
int main()
{
int n,minn=0x3f3f3f3f,mini,flag = 1;
cin>>n;
for(int i = 1; i<=9; i++) {
scanf("%d",a+i);
if(a[i] <= minn) {
minn = a[i];
mini = i;
}
}
if(n < minn) {
puts("-1");return 0 ;
}
int zxz = n/minn;//一共就 這麼多位
for(int i = zxz; i>=1; i--) {
for(int j = 9; j>=1; j--) {
if(a[j] > n) continue;
if( n-a[j] < (i-1)*minn) continue;
ans[i] = j;
n-=a[j];
break;
}
}
for(int i = zxz; i>=1; i--) printf("%d",ans[i]);
return 0 ;
}
附上wa的程式碼:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
int bk[500];
int a[22];
int main()
{
int n,minn=0x3f3f3f3f,mini,flag = 1;
cin>>n;
for(int i = 1; i<=9; i++) {
scanf("%d",a+i);
if(a[i] <= minn) {
minn = a[i];
mini = i;
}
}
if(n < minn) {
puts("-1");return 0 ;
}
int zxz = n/minn;
if(n%minn == 0) {
for(int i = 1; i<=zxz; i++) putchar(mini+'0');
return 0 ;
}
zxz--;
int res = n-zxz*minn,resi;
for(int i = 1; i<=9; i++) {
if(a[i] <= res) {
resi = i;
}
}
for(int i = 1; i<=zxz; i++) putchar(mini + '0');
putchar(resi+'0');
return 0 ;
}