HDU 5445 Food Problem, UVa 10163 Storage Keepers, POJ 3260 The Fewest Coins(2회 dp)
Food Problem문제: n종의 음식, m종의 차를 드리겠습니다. 각 음식은 3가지 속성 에너지치 t, 부피 u, 수량 v가 있습니다.각 차마다 세 개의 속성치 용량 x, 가격 y, 수량 z가 있다.
문제는 최소한 p에너지의 요구에 도달할 수 있는 최소 비용이 얼마이고 50000보다 크면 TAT를 출력하는 것이다
분석: 두 번의 다중 가방 dp는 최소한 p에너지의 최소 부피를 dp로 만든 다음에 50000에서 소비한 다음에 dp로 부피를 낸다. 만족하기 전의 최소 부피에서 답을 찾는다.
왜 부피 dp로 비용을 내지 않습니까?수량급이 어느 정도인지 보시면 알맞은 상태를 골라서 복잡도를 줄여야 돼요. 233.
바이너리 최적화 기억 233
코드://
// Created by TaoSama on 2015-09-25
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, m, p;
int dp[60005];
//1: dp[i][j]:= i desert j energy's minimum size
//2: dp[i][j]:= i truck j cost's maximum size
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
int t; scanf("%d", &t);
while(t--) {
scanf("%d%d%d", &n, &m, &p);
memset(dp, 0x3f, sizeof dp);
dp[0] = 0;
for(int i = 1; i <= n; ++i) {
int w, v, c; scanf("%d%d%d", &w, &v, &c);
for(int k = 1; c > 0; c -= k, k <<= 1) {
int mul = min(k, c);
for(int j = p + 100; j >= mul * w; --j)
dp[j] = min(dp[j], dp[j - mul * w] + mul * v);
}
}
int V = INF;
for(int i = p; i <= p + 100; ++i) V = min(V, dp[i]);
// printf("V: %d
", V);
memset(dp, 0, sizeof dp);
int ans = INF;
for(int i = 1; i <= m; ++i) {
int v, w, c; scanf("%d%d%d", &v, &w, &c);
for(int k = 1; c > 0; c -= k, k <<= 1) {
int mul = min(k, c);
for(int j = 50000; j >= mul * w; --j) {
dp[j] = max(dp[j], dp[j - mul * w] + mul * v);
if(dp[j] >= V) ans = min(ans, j);
}
}
}
if(ans == INF) puts("TAT");
else printf("%d
", ans);
}
return 0;
}
Storage Keepers
제목: n<100개의 창고 m<=30개의 관리자가 있습니다. 관리자마다 능력치 P(다음 줄에 m개, 관리자마다 능력치를 표시)가 있습니다. 창고는 한 명의 관리자만 관리할 수 있습니다.그러나 모든 관리자는 k개의 창고를 관리할 수 있다(그러나 이 창고에 분배된 안전치는 p/k,k=0,1에 불과하다...매달 회사에서 관리원에게 임금을 주어야 한다. 고용된 관리자의 임금은 그들의 능력치 p와 각 창고의 안전치가 가장 높은 전제에서 임금 총액을 최소화해야 한다. 최대 안전치를 수출하고 가장 적은 비용을 수출해야 한다.
분석: 다중 가방과 유사한 dp상태 두 번 코드 보기 첫 번째 dp에서 안전값이 나왔고 두 번째 이 상태에서 최소한의 비용을 찾아 초기화에 주의하고 잘 생각해 보세요.
코드://
// Created by TaoSama on 2015-08-12
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, m, p[35];
int f[35][105], g[35][105];
//dp[i][j]:= i people look after j storages max safe, min wage
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
while(scanf("%d%d", &m, &n) == 2 && (n || m)) {
for(int i = 1; i <= n; ++i) scanf("%d", p + i);
memset(f, 0, sizeof f);
f[0][0] = INF; //initialization is so difficult!
for(int i = 1; i <= n; ++i) {
for(int j = 0; j <= m; ++j) {
f[i][j] = f[i - 1][j]; //zero exception
for(int k = 1; k <= p[i] && k <= j; ++k)
f[i][j] = max(f[i][j], min(f[i - 1][j - k], p[i] / k));
}
}
int L = f[n][m];
if(!L) {printf("0 0
"); continue;}
memset(g, 0x3f, sizeof g);
g[0][0] = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 0; j <= m; ++j) {
g[i][j] = g[i - 1][j];
for(int k = 1; k <= p[i] && k <= j; ++k) {
int s = p[i] / k; //at least
if(s >= f[n][m]) g[i][j] = min(g[i][j], g[i - 1][j - k] + p[i]);
}
}
}
int Y = g[n][m];
printf("%d %d
", L, Y);
}
return 0;
}
The Fewest Coins
제목: 화폐의 종류수와 총 구매치를 제시하고 각 화폐의 가치와 수량을 제시한다.
사장님도 모든 종류의 화폐를 가지고 있지만 수량 제한이 없어요. 물건을 살 때 가치가 정해진 가치를 초과하면 사장님이 거슬러 줍니다.
최소한의 교류 화폐의 수량을 구하다
분석: 두 번 dp, 첫 번째 다중 가방에서 동전을 얼마나 썼는지 구하고 두 번째 완전 가방에서 동전을 얼마나 찾았는지 구하고 최소치를 구한다.
가장 중요한 것은 상계의 처리다.상계는 maxw*maxw+m(maxw 최대 액면가의 지폐), 즉 24400위안임을 알 수 있다.
증명서를 붙이다.
만약에 구매자의 지불 금액이 maxw*maxw+m보다 크면 즉시 지불하는 동전의 수량은 maxw보다 크다. 비둘기 바구니 원리에 따라 적어도 두 개는 maxw에 대한 모형의 값과 같다.
즉 이 부분의 동전은 더 적은 맥스로 대체할 수 있다는 것이다.증명이 끝나다.
진심으로 증명을 몰라도 괜찮아요. 결론을 기억하면 돼요. 진심으로 결론을 기억하고 싶지 않아도 돼요. 수조를 크게 만들면 돼요.
코드://
//
//
// Created by TaoSama on 2015-03-30
// Copyright (c) 2015 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
int n, t, dpp[25000], dpn[15000], c[105], v[105];
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
cin >> n >> t;
for(int i = 1; i <= n; ++i) cin >> v[i];
for(int i = 1; i <= n; ++i) cin >> c[i];
memset(dpp, 0x3f, sizeof dpp);
dpp[0] = 0;
for(int i = 1; i <= n; ++i) {
int k = 1;
while(c[i] > 0) {
int t = min(c[i], k);
for(int j = t + 120 * 120; j >= t * v[i]; --j)
dpp[j] = min(dpp[j], dpp[j - t * v[i]] + t);
c[i] -= k; k <<= 1;
}
}
/*for(int i = 0; i <= t + 120 * 120; ++i)
if(dpp[i] != INF) printf("dpp[%d]: %d
", i, dpp[i]);*/
memset(dpn, 0x3f, sizeof dpn);
dpn[0] = 0;
for(int i = 1; i <= n; ++i)
for(int j = v[i]; j <= 120 * 120; ++j)
dpn[j] = min(dpn[j], dpn[j - v[i]] + 1);
/*for(int i = 0; i <= 120 * 120; ++i)
if(dpn[i] != INF) printf("dpn[%d]: %d
", i, dpn[i]);*/
int ans = INF;
for(int i = 0; i <= 120 * 120; ++i)
ans = min(ans, dpp[t + i] + dpn[i]);
if(ans == INF) ans = -1;
cout << ans << endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
//
// Created by TaoSama on 2015-09-25
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, m, p;
int dp[60005];
//1: dp[i][j]:= i desert j energy's minimum size
//2: dp[i][j]:= i truck j cost's maximum size
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
int t; scanf("%d", &t);
while(t--) {
scanf("%d%d%d", &n, &m, &p);
memset(dp, 0x3f, sizeof dp);
dp[0] = 0;
for(int i = 1; i <= n; ++i) {
int w, v, c; scanf("%d%d%d", &w, &v, &c);
for(int k = 1; c > 0; c -= k, k <<= 1) {
int mul = min(k, c);
for(int j = p + 100; j >= mul * w; --j)
dp[j] = min(dp[j], dp[j - mul * w] + mul * v);
}
}
int V = INF;
for(int i = p; i <= p + 100; ++i) V = min(V, dp[i]);
// printf("V: %d
", V);
memset(dp, 0, sizeof dp);
int ans = INF;
for(int i = 1; i <= m; ++i) {
int v, w, c; scanf("%d%d%d", &v, &w, &c);
for(int k = 1; c > 0; c -= k, k <<= 1) {
int mul = min(k, c);
for(int j = 50000; j >= mul * w; --j) {
dp[j] = max(dp[j], dp[j - mul * w] + mul * v);
if(dp[j] >= V) ans = min(ans, j);
}
}
}
if(ans == INF) puts("TAT");
else printf("%d
", ans);
}
return 0;
}
//
// Created by TaoSama on 2015-08-12
// Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, m, p[35];
int f[35][105], g[35][105];
//dp[i][j]:= i people look after j storages max safe, min wage
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
while(scanf("%d%d", &m, &n) == 2 && (n || m)) {
for(int i = 1; i <= n; ++i) scanf("%d", p + i);
memset(f, 0, sizeof f);
f[0][0] = INF; //initialization is so difficult!
for(int i = 1; i <= n; ++i) {
for(int j = 0; j <= m; ++j) {
f[i][j] = f[i - 1][j]; //zero exception
for(int k = 1; k <= p[i] && k <= j; ++k)
f[i][j] = max(f[i][j], min(f[i - 1][j - k], p[i] / k));
}
}
int L = f[n][m];
if(!L) {printf("0 0
"); continue;}
memset(g, 0x3f, sizeof g);
g[0][0] = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 0; j <= m; ++j) {
g[i][j] = g[i - 1][j];
for(int k = 1; k <= p[i] && k <= j; ++k) {
int s = p[i] / k; //at least
if(s >= f[n][m]) g[i][j] = min(g[i][j], g[i - 1][j - k] + p[i]);
}
}
}
int Y = g[n][m];
printf("%d %d
", L, Y);
}
return 0;
}
//
//
//
// Created by TaoSama on 2015-03-30
// Copyright (c) 2015 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
int n, t, dpp[25000], dpn[15000], c[105], v[105];
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
cin >> n >> t;
for(int i = 1; i <= n; ++i) cin >> v[i];
for(int i = 1; i <= n; ++i) cin >> c[i];
memset(dpp, 0x3f, sizeof dpp);
dpp[0] = 0;
for(int i = 1; i <= n; ++i) {
int k = 1;
while(c[i] > 0) {
int t = min(c[i], k);
for(int j = t + 120 * 120; j >= t * v[i]; --j)
dpp[j] = min(dpp[j], dpp[j - t * v[i]] + t);
c[i] -= k; k <<= 1;
}
}
/*for(int i = 0; i <= t + 120 * 120; ++i)
if(dpp[i] != INF) printf("dpp[%d]: %d
", i, dpp[i]);*/
memset(dpn, 0x3f, sizeof dpn);
dpn[0] = 0;
for(int i = 1; i <= n; ++i)
for(int j = v[i]; j <= 120 * 120; ++j)
dpn[j] = min(dpn[j], dpn[j - v[i]] + 1);
/*for(int i = 0; i <= 120 * 120; ++i)
if(dpn[i] != INF) printf("dpn[%d]: %d
", i, dpn[i]);*/
int ans = INF;
for(int i = 0; i <= 120 * 120; ++i)
ans = min(ans, dpp[t + i] + dpn[i]);
if(ans == INF) ans = -1;
cout << ans << endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.