題目描述
Matrix67要在下個月交給老師n篇論文,論文的內容可以從m個課題中選擇。由於課題數有限,Matrix67不得不重複選擇一些課題。完成不同課題的論文所花的時間不同。具體地說,對於某個課題i,若Matrix67計劃一共寫x篇論文,則完成該課題的論文總共需要花費Ai*x^Bi個單位時間(係數Ai和指數Bi均爲正整數)。給定與每一個課題相對應的Ai和Bi的值,請幫助Matrix67計算出如何選擇論文的課題使得他可以花費最少的時間完成這n篇論文。
輸入格式
第一行有兩個用空格隔開的正整數n和m,分別代表需要完成的論文數和可供選擇的課題數。
以下m行每行有兩個用空格隔開的正整數。其中,第i行的兩個數分別代表與第i個課題相對應的時間係數Ai和指數Bi。
對於30%的數據,n<=10,m<=5;
對於100%的數據,n<=200,m<=20,Ai<=100,Bi<=5。
輸出格式
輸出完成n篇論文所需要耗費的最少時間。
樣例數據
樣例輸入
10 3
2 1
1 2
2 1
樣例輸出
19
樣例說明
4篇論文選擇課題一,5篇論文選擇課題三,剩下一篇論文選擇課題二,總耗時爲2*4^1+1*1^2+2*5^1=8+1+10=19。可以證明,不存在更優的方案使耗時小於19。
題目分析
最近迷上了Matrix67
一道揹包水題?開long long
初始化f一定要初始0x7fffffff/2
偷了個懶memset初始爲0x7f,導致無限WA
源代碼
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
inline const LL Get_Int() {
LL num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
struct subject {
LL a,b;
} issue[505];
LL n,m,f[25][205];
LL Quick_Pow(LL a,LL b) {
LL ans=1;
while(b>0) {
if(b&1)ans=ans*a;
b>>=1;
a=a*a;
}
return ans;
}
int main() {
n=Get_Int();
m=Get_Int();
for(int i=1; i<=m; i++) {
issue[i].a=Get_Int();
issue[i].b=Get_Int();
}
for(int i=0; i<=m; i++)
for(int j=1; j<=n; j++)
f[i][j]=0x7fffffff/2;
for(int i=1; i<=m; i++)f[i][0]=0;
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
for(int k=0; k<=j; k++)
f[i][j]=min(f[i][j],f[i-1][k]+issue[i].a*Quick_Pow(j-k,issue[i].b));
printf("%lld\n",f[m][n]);
return 0;
}