[vijos1198] 最佳課題選擇


題目描述

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;
}

發佈了169 篇原創文章 · 獲贊 31 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章