日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

日志:贪心

發布時間:2023/12/3 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 日志:贪心 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

排隊接水

時間限制: 1 Sec 內存限制: 128 MB
題目描述
有n 個人在一個水龍頭前排隊接水,假如每個人接水的時間為ti ,請編程找出這n 個人
排隊的一種順序,使得n 個人的平均等待時間最小。
輸入
第一行為n(1<=n<=5000)。第二行分別表示第1 個人到第n 個人每人的接水時間t1,
t2…,tn,每個數據之間有一個空格。(0<=ti<=10000)
輸出
共兩行,第一行為一種排隊順序,即1 到n 的一種排列,且保證小序號靠前(如:“2 3”
與“3 2”,在平均等待時間一樣時,輸出“2 3”;第二行為這種排列方案下的平均等待時
間(輸出結果精確到小數點后兩位,在小數點后三進行四舍五入)。
樣例輸入
10
56 12 1 99 1000 234 33 55 99 812
樣例輸出
3 2 7 8 1 4 9 6 10 5
291.90
解析:
這題比較簡單,要使得后面等待的時間少,那么盡量讓接水時間短的人排在前面,于是
我們可以使用二級排序,優先讓接水時間短的人排在前面,如果接水時間一樣,就按讀入的
順序小的排在前面,這樣就能做到最優方案了,至于最終的時間,就模擬一下統計總時間,
然后除以人數。(需要注意的是,第一個人不用等待,但第一個人接水的時間就是第二個人
等待時間,最后一個人的接水時間沒意義,因為沒人等待了)

#include// 不難
#include
using namespace std;
struct ren{
int time,id;
}(p[5100]);
bool cmp(ren x,ren y){
if(x.time!=y.time)return x.time<y.time;
return x.id<y.id;
}
int main(){
int i,tot=0,n;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&p[i].time);
p[i].id=i;
}
sort(p+1,p+n+1,cmp);
for(i=1;i<=n;i++){
tot += (n-i)p[i].time;
printf("%d “,p[i].id);
}
printf(”%.2f",1.0tot/n);
return 0;
}

最大整數

時間限制: 1 Sec 內存限制: 128 MB
題目描述
設有n 個正整數(n<=20),將它們連接成一排,組成一個最大的多位數。
例如:n=3 時,3 個整數13,312,343 連接成的最大整數為:34331213
又如:n=4 時,4 個整數7,13,4,246 連接成的最大整數為:7424613
輸入
第1 行,n;
第2 行,n 個數。
輸出
連接成的多位數。
樣例輸入
3 13 312 343
樣例輸出
34331213
解析:
此題很容易想到使用貪心法,在考試時有很多同學把整數按從大到小的順序連接起來,
測試題目的例子也都符合,但最后測試的結果卻不全對。按這種標準,我們很容易找到反例:
12,121 應該組成12121 而非12112,那么是不是相互包含的時候就從小到大呢?也不一
定,如12,123 就是12312 而非12123,這種情況就有很多種了。是不是此題不能用貪
心法呢?
其實此題可以用貪心法來求解,只是剛才的標準不對。我們發現更最基本的排序一樣,
哪個數字在前,哪個數字在后,比較的是兩種方案的大小比較。假設已經有最優方案產生前
面的數字t,當前要比較先接a,還是先接b,我們可以比較t+a+b 和t+b+a(這里的“+”
是連接符號),如果t+a+b>=t+b+a,那么先接a,反之先接b。但其實只要比較a+b 和
b+a 就行了,因為t 是公共部分,于是基本的貪心策略就出來了:
先把整數轉換成字符串,然后比較a+b 和b+a,如果a+b>=b+a,就把a 排在b 的前
面,反之則把a 排在b 的后面。

#include//也不太難
#include
#include
using namespace std;
char s[1002],s1[1002],change[1002];
void charu(){
int a=atof(s);
int b=atof(s1);
int l=strlen(s);
int l1=strlen(s1);
if(apow(10,l1)+b>=bpow(10,l)+a) strcat(s,s1);
else{
strcpy(change,s);
strcpy(s,s1);
strcat(s,change);
}
}
int main(){
int i,n;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%s",s1);
if(i==1){
strcpy(s,s1);
continue;
}
charu();
}
printf("%s",s);
}

紀念品分組【NOIP2007】

時間限制: 1 Sec 內存限制: 128 MB
題目描述
元旦快到了,校學生會讓樂樂負責新年晚會的紀念品發放工作。為使得參加晚會的同學所獲
得的紀念品價值相對均衡,他要把購來的紀念品根據價格進行分組,但每組最多只能包括兩
件紀念品, 并且每組紀念品的價格之和不能超過一個給定的整數。為了保證在盡量短的時
間內發完所有紀念品,樂樂希望分組的數目最少。
你的任務是寫一個程序,找出所有分組方案中分組數最少的一種,輸出最少的分組數目。
輸入
含n+2 行:
第1 行包括一個整數w,為每組紀念品價格之和的上限;
第2 行為一個整數n,表示購來的紀念品的總件數;
第3-n+2 行每行包含一個正整數Pi(5<=Pi<=w),表示所對應紀念品的價格。
輸出
僅一行,包含一個整數,即最少的分組數目。
樣例輸入
100
9 90
20
20
30
50
60
70
80
90
樣例輸出
6
提示
50%的數據滿足: 1<=n<=15
100%的數據滿足: 1<=n<=30000,80<=W<=200
解析:
題目要求每個組最多分兩個紀念品,如果是小的數字,那么它可能可以跟很多其他數字
組合,比如樣例:90 20 20 30 50 60 70 80 90,比如20 可以有很多的組合選擇;
但大的數字可以組合的機會比較少,比如90 沒的選擇,80 只能跟20 組合才不會超過100,
因此我們發現可以從較大數字優先著手:
首先排序,當前剩余數字中最大的數字如果能跟最小的數字組合,就讓它們分為一組,
否則最大數字單獨一組,并彈掉最大的數字,重復上述操作,直到數字取光,那么構成的組
數即為答案。

#include //也也不太難
#include
#include
#include
using namespace std;
int main(){
int i,n,w,tot,a[30002],place=1;
scanf("%d%d",&w,&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
tot=n;
for(i=n;i>place;i–){
if(a[i]+a[place]<=w){
tot–;
place++;
}
}
printf("%d",tot);
}

零件分組

時間限制: 1 Sec 內存限制: 128 MB
題目描述
某工廠生產一批棍裝零件,每個零件都有一定的長度(li)和重量(wi).現在為了加工需
要,要將它們分成若干組,使每一組的零件都能排成一個長度和重量都不下降(若i<j,則
li<=lj,wi<=wj)的序列。請問至少要分成幾組。
輸入
第一行為一個整數n(n<=1000),表示零件的個數。第二行有n 對正整數,每對正整數表示
這些零件的長度和重量,長度和重量均不超過10000。
輸出
僅一行,即最少分成的組數。
樣例輸入
58
4
3 8
2 3
9 7
3 5
樣例輸出
2
提示
二級排序
解析:
首先我們二級排序,那么問題就只需要比較沒有排序的另一邊數據,比如1 3 2 6 4
7 5,剛開始1 就分成組1,元素為{1},當3 來的時候,可以放到組1,就不額外增加組
了{1, 3}, 2 來的時候有分歧了,可以是{1,2} {3},也可以是{1,3} {2},那么我
們發現兩種情況其實效果一樣,因為每個分組在乎的是最后一個數字,那么我們任意選擇
{1,3}{2}的方案,因為這樣就不用調整3 了。再來6 的時候,我們發現,6 接到3 后面
比較好,使得兩組末尾的數字變為{6}{2},比{6}{3}要好。4 來的時候,接到2 后面,7
來的時候接6 后面,5 來的時候接4 后面,于是方案就為{1,3,6,7}{2,4,5}
這個時候貪心策略就自然出來了,也就是每個數字開始,往后取數字,取比它大的接在
后面,比它小的先忽略,一直取到數列最后,構成一個分組。接下來重新開始選擇數字,構
成第二個分組,直到數列中的元素取完。那么最終有多少組就是答案。

#include//這道題的本質就是記錄最小值更新的次數,我覺得我編的比題解要更好一些
#include
#include
#include
using namespace std;
int main(){
int n,l[1002],w[1002],i,min,judge=1,tot=1;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&l[i],&w[i]);
}
sort(l+1,l+1+n);
for(i=2;i<=n;i++){
if(judge){
if(w[i]<w[i-1]){
tot++;
judge=0;
min=w[i];
}//一開始min相當于w[i-1]
}
else{
if(w[i]<min) tot++;
}
}
printf("%d",tot);
}

總結

以上是生活随笔為你收集整理的日志:贪心的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。