您的位置:首页 > 运维架构

Stamps and Envelope Size UVA - 242

2017-10-12 14:13 465 查看
动态规划的思想,dp[i][j]其中i代表剩余的需要“填充”的资金的数量、j代表着剩余的可以使用的邮票的数量,如果当前放入的邮票的面值为a,那么如果dp[i-a][j-1]为真,则dp[i][j]就肯定为真,如果放入该邮票之后i-a为0,那么dp[i-a][j-1]就肯定为真,如果j-1为0同时i-a不为0,说明当前的放置方法不能将资金全部“填充”,则dp[i][j]就为假,如果i-a以及j-1均不为0,那么就枚举+递归,继续判断是否存在一种放置方法使得在现有的可放置的邮票数量内“填充”完所有的资金,具体实现见如下代码:

package a;//实际提交的时候记得去掉包名

import java.util.Arrays;
import java.util.Scanner;

public class Main {

int S,N;
int[][] stamp=new int[12][12];
int[][] dp=new int[1010][12];
int ans,key;

public void Init(){
for(int i=0;i<1010;i++)
Arrays.fill(dp[i],-1);
}

public boolean DP(int i,int j,int s){
if(dp[j][s]!=-1){
if(dp[j][s]==0) return false;
else return true;
}
if(j==0){
dp[j][s]=1;
return true;
}
if(s==0){
dp[j][s]=0;
return false;
}
for(int k=1;k<=stamp[i][0];k++){
if(j>=stamp[i][k]&&DP(i,j-stamp[i][k],s-1)){
dp[j][s]=1;
return true;
}
}
dp[j][s]=0;
return false;
}

public int judge(int a,int b){
if(stamp[a][0]<stamp[b][0]) return a;
if(stamp[a][0]>stamp[b][0]) return b;
for(int ind=stamp[a][0];ind>=0;ind--){
if(stamp[a][ind]<stamp[b][ind]) return a;
if(stamp[a][ind]>stamp[b][ind]) return b;
}
return a;
}

public void Solve(){
Scanner scan=new Scanner(System.in);
while(scan.hasNext()) {
S=scan.nextInt();
if(S==0) break;
N=scan.nextInt();
for(int i=0;i<N;i++){
stamp[i][0]=scan.nextInt();
for(int j=1;j<=stamp[i][0];j++){
stamp[i][j]=scan.nextInt();
}
}
ans=-1;
for(int i=0;i<N;i++){
int record=0;
Init();
for(int j=1;;j++){
if(DP(i,j,S)){
record=j;
}
else break;
}

if(record==ans){
key=judge(key,i);
}
if(record>ans){
key=i;
ans=record;
}
}
System.out.printf("max coverage =%4d :",ans);
for(int i=1;i<=stamp[key][0];i++){
System.out.printf("%3d",stamp[key][i]);
}
System.out.println();
}
}

public static void main(String[] args){
Main a=new Main();
a.Solve();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: