Input
The first line of input is an integer T which indicates the sum of test case. Each of the following T lines contains an integer n(1≤n≤105), which is the total money Shawn need to give to the customer.
Output
For each test case, output "Case i: Result" in one line where i is the case number and Result is the least number of changes Shawn need to give customer.
Sample Input
3 4 10 19
Sample output
Case 1: 2 Case 2: 2 Case 3: 4
Hint
Case 1: 4=3+1 Case 2: 10=5+5 Case 3: 19=6+6+6+1
第一反应是完全背包,无奈写炸TLE:
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i],f[i][v]|0<=k*c[i]<=v}
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
int T,V;
int w[4] = {6,5,3,1};
int dp[100005];
cin >> T;
for (int num = 1;num <= T;num++){
cin >> V;
for (int i = 0;i <= V;i++) dp[i] = i;
for (int i = 0;i < 4;i++){
for (int k = 0;k * w[i] <= V;k++){
for (int j = V;j >= k * w[i];j--){
dp[j] = min(dp[j],dp[j - k * w[i]]+ k);
}
}
}
printf("Case %d: %d\n",num,dp[V]);
}
return 0;
}
查题解发现可以直接套规律......
#include <stdio.h>
int a[12]={1,2,1,2,1,1,2,2,2,2,2,2};
int main(){
int t,n,sum;
scanf("%d",&t);
for(int i=0;i<t;i++){
scanf("%d",&n);
sum=0;
while(n>12){
n-=6;
sum++;
}
sum+=a[n-1];
printf("Case %d: %d\n",i+1,sum);
}
}
后来仔细研读完全背包,发现应该优化为01背包.....看来本菜真的是忘完了(背包详情讲解看另一篇《背包九讲》)
procedure CompletePack(cost,weight)
forv=cost..V
f[v]=max{f[v],f[v-cost]+weight}
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
int T,V;
int w[4] = {6,5,3,1};
int dp[100005];
cin >> T;
for (int num = 1;num <= T;num++){
cin >> V;
for (int i = 0;i <= V;i++) dp[i] = i;
for (int i = 0;i < 4;i++){
for (int j = w[i];j <= V;j++){
dp[j] = min(dp[j],dp[j-w[i]]+1);
}
}
printf("Case %d: %d\n",num,dp[V]);
}
return 0;
}