D - Mixing Experiment
D: Mixing Experiment - AtCoder Beginner Contest 054 | AtCoder
薬品をにする最小費用を求める問題。
制約も小さいので、でナップサックをすると解ける。
更新をを薬品の最小の比だと思い込んでて時間を溶かした。
具体的には、漸化式を
int div=(int)gcd((ll)(j+val[i+1].first),(ll)(k+val[i+1].second)); pii ni=mp((j+val[i+1].first)/div,(k+val[i+1].second)/div); cmin(dp[i+1][ni.first][ni.second],dp[i][j][k]+c[i+1]);
こんな形で更新してた。
頭を冷やしてみると、比の足し算はやばい事がわかるし、比はとの間にしか成り立たない関係ということもわかる。
反省。
#include<bits/stdc++.h> #define vi vector<int> #define vvi vector<vector<int> > #define vl vector<ll> #define vvl vector<vector<ll>> #define vb vector<bool> #define vc vector<char> #define vs vector<string> using ll = long long; using ld =long double; #define int ll #define INF 1e9 #define EPS 0.0000000001 #define rep(i,n) for(int i=0;i<n;i++) #define loop(i,s,n) for(int i=s;i<n;i++) #define all(in) in.begin(), in.end() template<class T, class S> void cmin(T &a, const S &b) { if (a > b)a = b; } template<class T, class S> void cmax(T &a, const S &b) { if (a < b)a = b; } #define MAX 9999999 using namespace std; typedef pair<int, int> pii; typedef pair<int,pii> piii; #define mp make_pair long long gcd(long long a, long long b) {return b ? gcd(b, a % b) : a;} long long lcm(long long m, long long n ){ if((0 == m )||( 0 == n ))return 0; return ((m / gcd(m, n)) * n); } int dp[41][401][401]; signed main(){ int n; cin>>n; pii comp; cin>>comp.first>>comp.second; rep(i,n)rep(j,401)rep(k,401)dp[i][j][k]=INF; dp[0][0][0]=0; vector<pii>val; vector<int>c(n); rep(i,n){ pii temp; cin>>temp.first>>temp.second; cin>>c[i]; val.push_back(mp(temp.first,temp.second)); dp[i][val[i].first][val[i].second]=c[i]; } rep(i,n-1){ rep(j,401){ rep(k,401){ if(dp[i][j][k]==INF)continue; cmin(dp[i+1][j][k],dp[i][j][k]); pii ni=mp((j+val[i+1].first),(k+val[i+1].second)); cmin(dp[i+1][ni.first][ni.second],dp[i][j][k]+c[i+1]); } } } int ans=INF; rep(i,401)rep(j,401){ int div=gcd(i,j); if(i&&j){ if(i/div==comp.first&&j/div==comp.second)cmin(ans,dp[n-1][i][j]); } } if(ans==INF)ans=-1; cout<<ans<<endl; }