题意分析
状态设计
dp[i][j]表示前i个课题,分配j篇论文的最少时间
状态转移
dp[i][j] = min(dp[i][j], dp[i-1][k]+c[i][j-k])
其中c[i][j-k]意为第i个课题,写j-k篇论文的时间
代码总览
#include<bits/stdc++.h>
using namespace std;
const int nmax = 205;
const int INF = 0x3f3f3f3f;
typedef long long ll;
ll a[25],b[25];
ll c[25][205];
ll dp[20][205];
int n,m;
ll pow(ll x, ll t){
ll ans = 1;
if(x == 1 || t == 0) return 1;
else{
while(t){
ans *= x;
t--;
}
return ans;
}
}
void init(){
for(int i = 1;i<=m;++i)
for(int j = 1;j<=n;++j)
c[i][j] = a[i] * pow((ll)j,b[i]);
}
void getdp(){
memset(dp,INF,sizeof dp);
for(int i = 0;i<=n;++i) dp[1][i] = c[1][i];
for(int i = 2;i<=m;++i){
for(int j = 0;j<=n;++j){
dp[i][j] = dp[i-1][j];
for(int k = 0;k<=j;++k){
dp[i][j] = min(dp[i][j],dp[i-1][k] + c[i][j-k]);
}
}
}
}
int main(){
scanf("%d %d",&n,&m);
for(int i = 1;i<=m;++i) scanf("%lld %lld",&a[i],&b[i]);
init();
getdp();
printf("%lld\n",dp[m][n]);
return 0;
}