수학
질문 : 합계가 K를 나눌 수 있도록 n 개의 양의 정수를 선택하고 이러한 n 개의 정수 중 가장 큰 수는 가능한 한 작습니다. 최대 값은 가능한 한 작기 때문에 최소 합계가 필요하며 최소 합계를 n 개의 숫자로 균등하게 나누어 최대 값을 찾습니다.
n <= k 일 때, 가장 작은 합계는 K이고, n 개의 숫자 중 가장 큰 것은 k / n 반올림, 반올림
방법 : (n + k-1) / k;
n> k 인 경우 최소 합계는 n / k 반올림 한 다음 * K이며, n 숫자의 최대 수는 최소 합계를 n으로 나눈 다음 반올림합니다.
사실, n과 K의 가장 작은 합에 관계없이 n / k는 반올림 된 다음 * K입니다.
AC 코드
#include <iostream>
using namespace std;
int main(){
long long n,k,sum,ans;
int T;
cin >> T;
for(int i = 0;i < T;i++){
cin >> n >> k;
sum =(n + k -1)/k * k;
ans = (sum + n -1)/n;
cout << ans << endl;
}
//system("pause");
return 0;
}
생각
질문의 의미 : n 개의 숫자, n 개의 숫자 및 k를 제공합니다. 첫 번째 숫자는 제품의 시작 가격이고 그 다음에는 매월 인상 된 금액이 표시됩니다. > 월별 가격 인상 전후의 모든 사람에게 <= k / 100을 요구합니다.
가격 인상 전 / 가격 인상 후 <= k / 100 가격 인상 전 100 <= k 가격 인상 후 나누기 대신 곱셈을 사용할 수 있습니다. 정밀도 손실 문제를 피하십시오.
위의 공식은 매월 충족되어야하므로 만족스럽지 않으면 가격 만 올릴 수 있습니다! ! ! , 최소한 총 가격이 얼마나 변경되었는지 확인하십시오. 따라서 위의 공식이 만족스럽지 않으면 위의 공식을 만족할 때까지 가격을 올리기 전에 가격을 올리기 만하면됩니다.
참고
첫 번째 테스트 사례에서 예를 들어 p0을 50으로, p1을 49로 늘리고 배열 [20150,50,202,202]를 가져올 수 있습니다. 그런 다음 다음 인플레이션 계수를 얻습니다.
AC 코드
#include <iostream>
using namespace std;
int main(){
int T,n;
int k;
cin >>T;
long long sum,x,ans,sum1;
for(int t = 0;t < T;t++){
cin >> n >> k;
ans = 0;
cin >> sum;
for(int i = 1;i < n;i++){
cin >> x;
if(x*100 > sum *k){
//cout << x << " x" << endl;
sum1 = (100*x + k -1)/k;
ans+=(sum1-sum);
sum = sum1;
}
sum +=x;
}
cout << ans << endl;
}
//system("pause");
return 0;
}
탐욕스러운
질문의 의미 : n 개의 연결된 체인에서 가장 긴 단순한 링을 찾도록합시다 (링을 원을 그리며 각 지점을 한 번만 통과). 따라서 ai> bi도 만족합니다. 즉, 교차 모서리도 만족하므로 매번 ai 추가-bi의 길이는 abs (ai-bi)이지만 ai == bi 일 때 i와 i -2 체인은 연결할 수 없습니다.
Greedy, i 번째 기사의 경우 i-2 번째 기사 (ai! = bi)와 연결될 수 있으면 연결하는 것이 길고 연결하지 않는 것이 무엇인지 판단한 다음 긴 것을 선택하여 저장합니다. 현재 다음 체인에 기여하는 가장 큰 반지, i 번째 체인의 경우 그림을 그리는 것이 어렵지 않습니다. i-2가 연결되어 있지 않으면 (i-2 위의 지점을 통과하지 않고) 나중에 i-2가 도움이되지 않으므로 다음 작업을 수행 할 수 있습니다. 후유증이 없기 때문에 욕심을 낼 수 있습니다. 그런 다음 기존 최대 값과 비교하십시오.
AC 코드
#include <iostream>
#include <stdlib.h>
using namespace std;
int num[100200];
int a[100020];
int b[100020];
long long max(long long a,long long b){
return a > b?a:b;
}
int main(){
int T;
int n;
long long ans,sum,x,x1;
cin >> T;
for(int t = 0;t < T;t++){
scanf("%d",&n);
ans = 0;
sum = 0;
for(int i = 0;i < n;i++)
scanf("%d", &num[i]);
for(int i = 0;i < n;i++)
scanf("%d",&a[i]);
for(int i = 0;i < n;i++)
scanf("%d",&b[i]);
ans = 0;
for(int i = 1;i < n;i++){
if(a[i] == b[i])
sum = 0;//前面的连不起来 如果sum是max就已经被收了就没有意义了
x = num[i]+1 + abs(a[i]-b[i]);//只取第i个
x1 = sum;//在前面的基础上取第i个
if(x1)
x1-=abs(a[i]-b[i]);
x1+=(1+num[i]);
sum = max(x,x1);//取了第i个的最大环 如果只取i 比取i和之前相连,就说明i之前的没有意义,
//可以扔了
ans = max(ans,sum);
}
printf("%lld\n",ans);
}
//system("pause");
return 0;
}