洛谷P1860 新魔法藥水
阿新 • • 發佈:2019-01-10
動態規劃:
這個題目調了我好久。。。。結果迴圈變數寫錯了。。。
而且題目有個坑!!!只能用開始給你的$v$元買入東西
迴歸正題:
我們定義狀態$ans[i][j]$表示第$i$個物品用了至多$j$次魔法的最小花費,但是我們發現這樣子的話不好與合成關係聯絡在一起,那麼我們再定義一個數組$f[i][j]$表示某一個合成關係中,前$i$個物品中用至多$j$次魔法合成的最小花費
那麼最後就普通$dp$就行了
#include<iostream> #include<cstdio> #include<cstring> #define inf 0x7f7f7f7f #define M 300 #define K 31 using namespace std; struct Magic { int to,num,thing[M]; }magic[M]; int n,m,v,k; int pay[M],get[M],f[M][M],ans[M][M],dp[M][1007]; int main() { scanf("%d%d%d%d",&n,&m,&v,&k); for(int i=1;i<=n;++i) scanf("%d%d",&pay[i],&get[i]); for(int i=1;i<=m;++i) { scanf("%d%d",&magic[i].to,&magic[i].num); for(int j=1;j<=magic[i].num;++j) scanf("%d",&magic[i].thing[j]); } for(int i=1;i<=n;++i) for(int j=0;j<=k;++j) ans[i][j]=pay[i]; for(int l=1;l<=k;++l) { for(int i=1;i<=m;++i) { for(int j=1;j<=magic[i].num;++j) for(int o=0;o<l;++o) { f[j][o]=inf; for(int oo=0;oo<=o;++oo) f[j][o]=min(f[j][o],f[j-1][o-oo]+ans[magic[i].thing[j]][oo]); } ans[magic[i].to][l]=min(ans[magic[i].to][l],f[magic[i].num][l-1]); } } // for(int i=1;i<=n;++i) // { // for(int j=1;j<=m;++j) // printf("%d ",ans[i][j]); // printf("\n"); // } for(int i=1;i<=n;++i) for(int j=0;j<=k;++j) for(int o=0;o<=k-j;++o) for(int l=ans[i][j];l<=v;++l) dp[j+o][l]=max(dp[j+o][l],dp[o][l-ans[i][j]]+get[i]-ans[i][j]); printf("%d",dp[k][v]); return 0; }