商店購物題解
阿新 • • 發佈:2022-03-15
商店購物!!!
- 請奆佬們潔身自好,好好打程式碼從我做起 -
題目大意:
在商店中,每一種商品都有一個價格。
商店 把一個或多個商品組合起來降價銷售,形成優惠方案,
編寫一個程式,計算顧客購買一定商品的花費,利用優惠使花費最少。
儘管有時候新增其他商品可以獲得更少的花費,但是你不能這麼做。
解析題目:
這道題就是五維暴力,但 易錯點很多,噁心,是道毒瘤題
不愧是IOI的真題
暴力,資料較小,且最多五種商品
注意!儘管有時候新增其他商品可以獲得更少的花費,但是你不能這麼做
比如你要買三個蘋果,兩根香蕉,花了11z
方案是三個蘋果,三根香蕉花了10z
那也不行,因為浪費了一根香蕉
(宣傳不浪費的IOI)
狀態:f(i,j,k,l,q)表示 買 i 的第一種商品 ,買 j 的第二種商品 ,買 k 的第三種商品 ,買 l 的第四種商品 ,買 q 的第五種商品 的最小花費
如果不足五種怎麼辦?其實不慌,比如如果有三種 ,l,q將一直等於0,不影響使用
我們還需要一個二維陣列p,p(i,j)表示第i種優惠裡商品j所需的數量。
模擬即可
詳細講解:
先來介紹一下沒什麼用快讀吧
在 C++ 中,讀入字元要比讀入數字快
因此,我們可以讀入字元,將其轉為數字
在一百萬次輸入後,快讀將比scanf快1秒
其實這道題不用快讀,是我打時不知道怎麼想的
inline int read() { int ans = 0; char c = getchar(); while ((c < '0' || c > '9') )//篩掉空格、換行等 { c = getchar(); } ans = c - '0';//正式開始讀入 c = getchar(); while (c >= '0' && c <= '9') { ans = (ans << 3) + (ans << 1);//位運算比正常計算快,這個位運算等價於ans*=10; ans += c - '0'; c = getchar(); } return ans; }//總之就生活小妙招了屬於是
見樣例,雖然 只有5種,
但編號不一定是1~5,我們需要在輸入時自行編號,一個h陣列即可,map會WA
由於一個編號會出現多次,要先判斷h[x]是否為0,是0才編號
for(int i=1;i<=s;i++)//s是方案數
{
n=read();
for(int j=1;j<=n;j++)
{
b=read();
if(h[b]==0)h[b]=++tmp;//編號
p[i][h[b]]=read();
}
money[i]=read();//money是 優惠方案的價錢 的意思
}
在下面也是一樣的
for(int i=1;i<=b;i++)//b是我們要買的種類數 { int x=read(); if(h[x]==0)h[x]=++tmp; //同上,是0才編號 need[h[x]]=read(); //need表示我們一共需要多少個 old[h[x]]=read();//old 表示原價 }
接下來是初始化
因為f(i,j,k,l,q)表示買 i 的第一種商品 ,買 j 的第二種商品 ,買 k 的第三種商品 ,買 l 的第四種商品 ,買 q 的第五種商品 的最小花費
所以預設是全用原價
for(int i=0;i<=need[1];i++)
{
for(int j=0;j<=need[2];j++)
{
for(int k=0;k<=need[3];k++)
{
for(int l=0;l<=need[4];l++)
{
for(int q=0;q<=need[5];q++)//五重暴力初始化,求出所有的原價
//注意也要考慮0,不買也不是不行
{
f[i][j][k][l][q]=old[1]*i+old[2]*j+old[3]*k+old[4]*l+old[5]*q;
}
}
}
}
}
誰寫的順口溜?
接下來是可怕的六重迴圈解析
for(int m=1;m<=s;m++)
{
程式碼:我裂開了
m表示當前考慮的方案
然後繼續看
我們要列舉i,j,k,l,q
對於範圍,不足 p[m]就不能實現方案了,超過need就浪費了
所以是p[m]~need
for(int i=p[m][1];i<=need[1];i++)
{
for(int j=p[m][2];j<=need[2];j++)
{
for(int k=p[m][3];k<=need[3];k++)
{
for(int l=p[m][4];l<=need[4];l++)
{
for(int q=p[m][5];q<=need[5];q++)//從i到q都一樣,只是表示的 要買的東西 不同
解析一下轉移方程
當求 f(i,j,k,l,q)時,
應該將其分解成子問題
顯然,我們只用考慮 賣完還需要的東西構成的子問題 加上 方案價格 再比較大小 即可
{
if(f[i][j][k][l][q]>=f[i-p[m][1]][j-p[m][2]][k-p[m][3]][l-p[m][4]][q-p[m][5]]+money[m])
{
f[i][j][k][l][q]=f[i-p[m][1]][j-p[m][2]][k-p[m][3]][l-p[m][4]][q-p[m][5]]+money[m];
}
}
別忘了括號
}
}
}
}
}